Point3

目次

はじめに

Point3 クラスは 3 次元の値を扱う汎用的なクラスです。座標、ベクトル、その他汎用的な項目等にも使えます。
また、オプションとして16進数6桁のカラー文字列も扱えます(RGB→HSB変換等)。
DHTML ではレイヤーのポジション(left,top,zIndex)等を一括して扱うことが可能です。
他クラスでも使われる再利用性の高いクラスです。

使用例

var p = new Point3( 10 , 20 , 30 );
var q = new Point3( 40 , 50 , 60 );

p.scale( 3 ); // p の中身を 3 倍
p.add( q );   // p と q を足したものを p に代入

status = p ; // 結果は Point3 : ( 70 , 110 , 150 )

var color0 = new Point3( 255 , 0 , 0 );
var color1 = new Point3( "00ff00" );

status = color0.toColor() + " : " + color1.getY() // 結果は ff0000 : 255

/* DHTML での使用例 */

var f = new Point3( 10 , 100 , 2 )
Elements["LAYER"].setPosition3( f );
// レイヤーの位置が left = 10 , top = 100 , zIndex = 2 となります。

インスタンス変数

number x ;
number y ;
number z ;
3 次元の値を扱うので、インスタンス変数は x,y,z の3つを有しています。

コンストラクタ

Point3();
Point3( number x0 , number y0 , number z0 );
Point3( number[] a );
Point3( string color ); // color は16進数6桁のカラー文字列(ff0000など)
Point3( Point3 p );
インスタンスを生成します。宣言の仕方は上の 5 つです。

ここで a は長さが 3 以上の配列です。この場合、x = a[0] , y = a[1] , z = a[2] となります。
引数なしでは x = 0 , y = 0 , z = 0 になります。

意味は Dimension クラス と同じですが、注意が必要なのは Point3( string color ) です。 例えば以下のようにインスタンスを生成します。
var p = new Point3( "ff0000" );
このとき、インスタンス変数は x=255(=0xff),y=0(=0x00),z=0(=0x00) となります。
x="ff",y="00",z="00" ではありませんので注意して下さい。
var p0 = new Point3();
var p1 = new Point3( 10 , 20 ,30 );
var p2 = new Point3( new Array( 40 , 50 , 60 ) );
var p3 = new Point3( "ffff00" );
var p4 = new Point3( p1 );

インスタンスメソッド

値の変更 : set
void set();
void set( number x0 , number y0 , number z0 );
void set( number[] a );
void set( string color );
void set( Point3 p );
インスタンス変数の値を変更します。
引数でセットされる値の意味はコンストラクタと同じです。
var p = new Point3( 10 , 20 , 30 );
p.set( 30 , 40 , 50 );

status = "("+p.getX()+","+p.getY()+","+p.getZ()+")" ; // 結果は (30,40,50)
値の変更(個別) : set*
void setX( number x0 );
void setY( number y0 );
void setZ( number z0 );
インスタンス変数 x,y,z の値を個別に変更します。
var p = new Point3( 10 , 20 );
p.setX( 30 );
p.setY( 40 );
p.setZ( 50 );

status = "("+p.getX()+","+p.getY()+","+p.getZ()+")" ; // 結果は (30,40,50)
値の取得 : get*
number getX();
number getY();
number getZ();
インスタンス変数 x,y,z の値を取得します。
var p = new Point3( 10 , 20 , 30 );

status = "("+p.getX()+","+p.getY()+","+p.getZ()+")" ; // 結果は (10,20,30)
イコール : equals , intEquals
boolean equals( Point3 p0 );
引数 p0 の持つインスタンス変数と等しいか判定します。 全て等しいとき true が返ります。
boolean intEquals( Point3 p1 );
引数 p1 と自分の持つインスタンス変数を整数にしたものを考え、等しいか判定します。 全て等しいとき true が返ります。
var p = new Point3( 0.1 , 1.2 , 2 );
var q = new Point3( 0 , 1 , 2.1 );

status = p.equals(q);    // 結果は false
status = p.intEquals(q); // 結果は true
数か判定 : isNaN
boolean isNaN();
インスタンス変数が、数かどうかを判定します。
x,y,z一つでも数でないものが含まれる場合、true が返ります。
var p = new Point3( "text" , 20 , 30 );

status = p.isNaN(); // 結果は true
絶対値 : absolute
void absolute();
インスタンス変数の値を絶対値に変換します。
var p = new Point3( -10 , 20 , 0 );
p.absolute();

status = "("+p.getX()+","+p.getY()+","+p.getZ()+")"; // 結果は (10,20,0)
加減演算 : add , sub
void add( Point3 p0 );
void sub( Point3 p1 );
Point3 クラスをベクトルとして考え加減演算を行います。
結果は引数だけオフセットしたものになります。 add は足し算、sub は引き算です。 しいて書くなら、a.add(b)a = a + b , a.sub(b) は a = a - b です。
var p0 = new Point3( 10 , 20 , 30 );
p0.add( new Point3( 30 , 40 , 50 ) );

status = "("+p0.getX()+","+p0.getY()+","+p0.getZ()+")"; // 結果は (40,60,80)

var p1 = new Point3( 10 , 20 , 30 );
p1.sub( new Point3( 10 , 30 , 50 ) );

status = "("+p1.getX()+","+p1.getY()+","+p1.getZ()+")"; // 結果は (0,-10,-20)
スケーリング : scale
void scale( number n );
インスタンス変数の値を引数(n)倍します。
var p = new Point3( 10 , 20 , 30 );
p.scale( 3 );

status = "("+p.getX()+","+p.getY()+","+p.getZ()+")"; // 結果は (30,60,90)
距離 : distance
number distance();
number distance( Point3 p );
Point3 クラスを座標と考え、引数 p までの距離を返します。
引数なしの場合は原点からの距離を返します。
var p = new Point3( 1 , 1 , 1 );
status = p.distance(); // 結果は 1.7320... ( √3 )

var q = new Point3( 3 , 3 , 3 );
status = q.distance( p ); // 結果は 3.4641... ( 2√3 )
角度 : angle
number angle( Point3 p );
Point3 クラスをベクトルと考え、引数(p)とのなす角を返します。
Dimension クラスと違い、引数なしでは使用できません。
返される値は2ベクトルがなす面上でのなす角なので気を付けて下さい。 単位は rad です。返される値の範囲は Math.acos() と同じで、0-π です。
var p = new Point3( 1 , 1 , 1 );
var q = new Point3( 1 , 0 , 1 );

status = p.angle( q ); // 結果は π/4 ( 45度 )
内積 : mulin
number mulin( Point3 p );
Point3 クラスをベクトルと考え、引数 p と内積した値を返します。
var p = new Point3( 10 , 20 , 30 );
var q = new Point3( 30 , 40 , 50 );

status = p.mulin(q); // 結果は 2600 (=10*30+20*40+30*50)
外積 : mulout
Point3 mulout( Point3 p );
Point3 クラスを3次元ベクトルと考え、引数(p)との外積を返します。
戻り値も Point3 クラスです。
var p = new Point3( 1 , 0 , 0 );
var q = new Point3( 0 , 1 , 0 );

status = p.mulout( q ); // 結果は ( 0 , 0 , 1 ) = p * q
大小 : max , min
number max();
number min();
インスタンス変数 x,y,z を比較して最も大きい(小さい)値を返します。
var p = new Point3( 10 , 20 , 30 );
status = p.max(); // 結果は 30

var q = new Point3( 40 , 50 , 60 );
status = q.min(); // 結果は 40
配列 : toArray
number[] toArray();
インスタンス変数 x,y,z の値を持つ長さ3の配列を生成し、取得します。
var p = new Point3( 10 , 20 , 30 );
var a = p.toArray();

status = a[0]+","+a[1]+","+a[2]; // 結果は 10,20,30
整数 : toInteger
Point3 toInteger();
インスタンス変数 x,y,z を整数にしたものを生成し、取得します。
内部では Math.floor(小数点以下は切り捨て)を使用しています。
var p = new Point3( 0.1 , 1.2 , 2 );
var q = p.toInteger();

status = "("+q.getX()+","+q.getY()+","+q.getZ()+")"; // 結果は (0,1,2)
色 : toColor
string toColor();
インスタンス変数 x,y,z をカラーの R , G , B と考え、16進数6桁のカラー値を返します。
var red  = new Point3( 255 , 0 , 0 );
var blue = new Point3("0000ff");

status = red.toColor()+" : "+blue.toColor(); // 結果は ff0000 : 0000ff
標準出力文字列 : toString
string toString();
Point3 クラスの標準出力文字列を返します。
返される文字列は "Point3 : "+"( "+this.x+" , "+this.y+" , "+this.z+" )" です。
var p = new Point3( 10 , 20 , 30 );

status = p // 結果は Point3 : ( 10 , 20 , 30 )

クラスメソッド

色座標変換( RGB → HSB ) : RGBtoHSB
Point3 RGBtoHSB( string rgb );
Point3 RGBtoHSB( Point3 rgb );
引数(rgb)のインスタンス変数 x,y,z をカラーの R , G , B と考え、色座標を RGB から HSB( Hue:色相 , Saturation:彩度 , Brightness:明度 ) に変換したものを生成し、返します。
返された(HSB に変換された) Point3 クラスのメンバ変数の値は x,y,z 共に 0 以上 1 以下の値 です。単位はありません。 一般的な H[deg],S[%],B[%] ではないので注意して下さい。
var red_RGB = new Point3( "ff0000" );
var red_HSB = Point3.RGBtoHSB( red_RGB );

status = red_HSB ; // 結果は Point3 : ( 0 , 1 , 1 )
色座標変換( HSB → RGB ) : HSBtoRGB
Point3 HSBtoRGB( string hsb );
Point3 HSBtoRGB( Point3 hsb );
今度は上のとは逆で引数(hsb)のインスタンス変数 x,y,z をカラーの H , S , B と考え、色座標を HSB から RGB に変換したものを生成し、返します。
指定できるメンバ変数の値の範囲は x,y,z 共に 0 以上 1 以下の値 です。 一般的なHSB指定の値の範囲ではないので注意して下さい。
var q_HSB = new Point3( 0.0 , 1.0 , 1.0 );
var q_RGB = Point3.HSBtoRGB( q_HSB );

status = q_RGB.toColor(); // 結果は ff0000 (=赤色)

メソッド一覧

Point3 クラスで使用できるメソッドのリストです。
メソッド名説明
voidsetインスタンス変数の設定
voidsetXインスタンス変数 x の設定
voidsetYインスタンス変数 y の設定
voidsetZインスタンス変数 z の設定
numbergetXインスタンス変数 x の取得
numbergetYインスタンス変数 y の取得
numbergetZインスタンス変数 z の取得
booleanequals等しいか判定
booleanintEquals整数にしたものが等しいか判定
booleanisNaN数か設定
voidabsolute絶対値に変換
voidaddベクトルの加算
voidsubベクトルの減算
voidscaleスケーリング
numberdistance距離
numberangle角度
numbermulin内積
Point3mulout外積
numbermax最も大きい値を取得
numbermin最も小さい値を取得
number[]toArray配列化したものを取得
Point3toInteger整数化したものを取得
stringtoColor16進数6桁のカラー文字列の取得
stringtoString標準出力文字列
クラスメソッド
Point3HSBtoRGB色座標変換 RGB → HSB
Point3RGBtoHSB色座標変換 HSB → RGB

補足

■ こんな使い方もできます 1
Dimension クラス と言いたいことは殆ど同じ。なので例だけ。
var persons = new Array(
    new Point3( "名前0" , "生年月日0" , "血液型0" ),
    new Point3( "名前1" , "生年月日1" , "血液型1" ),
    new Point3( "名前2" , "生年月日2" , "血液型2" ),
    new Point3( "名前3" , "生年月日3" , "血液型3" ),
    new Point3( "名前4" , "生年月日4" , "血液型4" )
);

status = persons[0].getX(); // 結果は 名前0
var matrix = new Point3(
    new Point3( "00" , "01" , "02" ),
    new Point3( "10" , "11" , "12" ),
    new Point3( "20" , "21" , "22" )
);

status = matrix.getX().getX(); // 結果は 00
■ こんな使い方もできます 2
これもまた Dimension クラス と同じ。端折ります。Point3 クラスには
Point3( number n );
という形式のコンストラクタがあり、次のようにインスタンスを生成する。
var p = new Point3( 20 );
同じように add と sub メソッドにも存在する。
void add( number a );
void sub( number s );
var p = new Point3( 10 , 25 , 40 );
p.add( 30 );

status = p ; // 結果は Point3 : ( 40 , 55 , 70 )
■ 色を扱うこと
Point3 クラスには色を扱うメソッドがありました。
toColor , RGBtoHSB , HSBtoRGB です。

な〜んか納得いかないって人はいませんか?
「Point3 クラス(幾何クラス)で色を扱うな!」とか。僕も結構そんなタイプです(おい)
当初、Point3 クラスと、色を扱うクラス Color クラスに分けられていました。でも、そんな大した機能(メソッド)もないのに一つのクラスにするのはどうかと思い、Point3 クラスにまとめられたわけです。

ということで、納得いかない人は Color クラスを作成して使いましょう。以下に Point3 クラスを継承した Color クラスを書いておきます。
// 先ず Point3 クラスを読み込んでおくこと

// Color クラスのコンストラクタを定義
function Color(){
    
    var a = arguments ;
    
    // 引数の数に応じて、super クラス(Point3 クラス)のコンストラクタを呼び出す
    switch( a.length ){
        case 0 : default : this.constructor(); break ;
        case 1 : this.constructor( a[0] ); break ;
        case 3 : this.constructor( a[0] , a[1] , a[2] ); break ;
    }
    
    // こうしておくと面白いけど、あとで面倒なことになりそう・・・
    this.r = this.x ;
    this.g = this.y ;
    this.b = this.z ;
    
}

// 継承
Color.prototype = new Point3 ;

// Point3 クラスのクラスメソッドを定義
Color.HSBtoRGB = function(c){ return new Color( Point3.HSBtoRGB(c) ); };
Color.RGBtoHSB = function(c){ return new Color( Point3.RGBtoHSB(c) ); };

// あとは Color クラスのメソッドをガンガン追加

Color.prototype.getRed   = function(){ return this.x ; };
Color.prototype.getGreen = function(){ return this.y ; };
Color.prototype.getBlue  = function(){ return this.z ; };

Color.prototype.toHSB = function(){ return Color.RGBtoHSB( this ); };
Color.prototype.toRGB = function(){ return Color.HSBtoRGB( this ); };

// これいいかも
Color.prototype.toString = function(){ return '#'+this.toColor(); };
ちょっといい加減な実装ですが(^^);、使用例なんかも
var red   = new Color( 0xff , 0x00 , 0x00 );
var green = new Color("00ff00");
var blue  = Color.HSBtoRGB( new Color( 2/3 , 1.0 , 1.0 ) );

alert( red );   // 結果は #ff0000
alert( green ); // 結果は #00ff00
alert( blue );  // 結果は #0000ff