/*********************************************************************
	
	=== Geometory Three-Dimension & Color ===
	
	* Point3 [ Point3.js ]
	
	* updated 2001/05/28
	
	mail : peace@skipup.com
	home : http://www.skipup.com/~peace/
	
*********************************************************************/



//public class Point3 extends Object
function Point3(){
	
	// protected object
	this.x ;
	this.y ;
	this.z ;
	
	/****************************** CONSTRUCTOR - BEGIN ******************************/
	
	var a = arguments ;
	
	switch( a.length ){
		case 0 : default : this.x = this.y = this.z = 0 ; break ;
		case 1 : { // Point3 || Array || string || other
			switch( typeof a[0] ){
				case "object" : { // Point3 || Array
					var o = a[0];
					if( o.constructor == Point3 ){ // Point3
						this.x = o.x ;
						this.y = o.y ;
						this.z = o.z ;
					}else if( o.constructor == Array ){ // Array
						this.x = o[0];
						this.y = o[1];
						this.z = o[2];
					}
					break ;
				}
				case "string" : { // string
					var p ;
					if( a[0].length == 6 ){
						p = parseInt( "0x"+a[0] );
					}else if( a[0].charAt(0) == '#' ){
						p = parseInt( "0x"+a[0].substr(1,6) );
					}else{
						p = Math.floor( a[0] );
					}
					this.x = ( p & 0xFF0000 ) >>> 0x10 ;
					this.y = ( p & 0x00FF00 ) >>> 0x08 ;
					this.z = ( p & 0x0000FF ) >>> 0x00 ;
					break ;
				}
				default : this.x = this.y = this.z = a[0]; // other
			}
			break ;
		}
		case 3 : { // number , number , number || other
			this.x = a[0];
			this.y = a[1];
			this.z = a[2];
			break ;
		}
	}
	
	/****************************** CONSTRUCTOR - E N D ******************************/
	
}

function setBasicMember__Point3__(){
	
	var P  = Point3 ;
	var PP = P.prototype ;
	
	// private string
	function digitHex2( p ){
		if( p < 0x00 ){
			return "00" ;
		}else if( p < 0x10 ){
			return "0"+p.toString(16);
		}else if( p > 0xff ){
			return "ff" ;
		}else{
			return p.toString(16);
		}
	}
	
	/****************************** SET_STATIC_MEMBER - BEGIN ******************************/
	
	// public static Point3
	P.RGBtoHSB = function(){
		var c = new P( arguments[0] );
		var cmax = c.max();
		var cmin = c.min();
		var h = 0.0 ;
		var s = ( cmax != 0.0 ) ? ( cmax - cmin )/cmax : 0.0 ;
		var b = cmax/0xFF;
		if( s != 0.0 ){
			var cc = new P( c );
			cc.scale( -1 );
			cc.add( cmax );
			cc.scale( 1/( cmax - cmin ) );
			if( c.x == cmax ){
				h = 0.0 + cc.z - cc.y ;
			}else if( c.y == cmax ){
				h = 2.0 + cc.x - cc.z ;
			}else{
				h = 4.0 + cc.y - cc.x ;
			}
			h /= 6.0 ;
			if( h < 0.0 ){
				h += 1.0 ;
			}else if( h > 1.0 ){
				h -= 1.0 ;
			}
		}
		return new P( h , s , b );
	};
	
	// public static Point3
	P.HSBtoRGB = function(){
		var v = new P( arguments[0] );
		var h = v.x ; // Hue        : 色相
		var s = v.y ; // Saturation : 彩度
		var b = v.z ; // Brightness : 明度
		var c = new P();
		if( s == 0.0 ){
			c.add( b );
		}else{
			var e = ( h - Math.floor( h ) )*6.0 ;
			var f = Math.floor( e );
			var g = e - f ;
			var n = b * ( 1.0 - s );
			var m = ( ( f & 1 ) == 0 ) ? b * ( 1.0 - s * ( 1.0 - g ) ) : b * ( 1.0 - s * g ) ;
			switch( f ){
				case 0 : c.set( b , m , n ); break ;
				case 1 : c.set( m , b , n ); break ;
				case 2 : c.set( n , b , m ); break ;
				case 3 : c.set( n , m , b ); break ;
				case 4 : c.set( m , n , b ); break ;
				case 5 : c.set( b , n , m ); break ;
			}
		}
		c.scale( 255.0 );
		c.add( 0.5 );
		return c.toInteger();
	};
	
	/****************************** SET_STATIC_MEMBER - E N D ******************************/
	
	/****************************** SET_METHOD - BEGIN ******************************/
	
	// public void
	PP.set = function(){
		var a = arguments ;
		var p ;
		switch( a.length ){
			case 0 : default : p = new P(); break ;
			case 1 : p = new P( a[0] ); break ;
			case 3 : p = new P( a[0] , a[1] , a[2] ); break ;
		}
		this.x = p.x ;
		this.y = p.y ;
		this.z = p.z ;
	};
	PP.setX = function( x ){ this.x = x ; };
	PP.setY = function( y ){ this.y = y ; };
	PP.setZ = function( z ){ this.z = z ; };
	
	// public object
	PP.getX = function(){ return this.x ; };
	PP.getY = function(){ return this.y ; };
	PP.getZ = function(){ return this.z ; };
	
	// public Array
	PP.toArray = function(){ return new Array( this.x , this.y , this.z ) ; };
	
	// public Point3
	PP.toInteger = function(){ return new P( Math.floor( this.x ) , Math.floor( this.y ) , Math.floor( this.z ) ); };
	
	// public string
	PP.toColor = PP.getColor = function(){ return digitHex2( Math.round( this.x ) ) + digitHex2( Math.round( this.y ) ) + digitHex2( Math.round( this.z ) ); };
	
	// public boolean
	PP.equals    = function( p ){ return ( this.x == p.x && this.y == p.y && this.z == p.z ); };
	PP.intEquals = function( p ){ return ( this.toInteger().equals( p.toInteger() ) ); };
	
	// public boolean
	PP.isNaN = function(){ return ( isNaN( this.x ) || isNaN( this.y ) || isNaN( this.z ) || this.x == "" || this.y == "" || this.z == "" ); };
	
	// public double
	PP.distance = function( p ){
		if( p ){
			var q = new P( this );
			q.sub( p );
			return q.distance();
		}else{
			return Math.sqrt( Math.pow( this.x , 2 )+Math.pow( this.y , 2 )+Math.pow( this.z , 2 ) );
		}
	};
	
	// public double
	PP.mulin = function( p ){ return this.x*p.x+this.y*p.y+this.z*p.z ; };
	
	// public Point3
	PP.mulout = function( p ){ return new P( this.y*p.z-p.y*this.z , this.z*p.x-p.z*this.x , this.x*p.y-p.x*this.y ); };
	
	// public double
	PP.max = function(){ return Math.max( Math.max( this.x , this.y ) , this.z ); };
	PP.min = function(){ return Math.min( Math.min( this.x , this.y ) , this.z ); };
	
	// public double
	PP.angle = function( p ){
		var result = this.mulin( p )/( this.distance()*p.distance() );
		if( Math.abs( result ) > 1.0 ) result /= Math.abs( result );
		return Math.acos( result );
	};
	
	// public void
	PP.absolute = function(){
		this.x = Math.abs( this.x );
		this.y = Math.abs( this.y );
		this.z = Math.abs( this.z );
	};
	
	// public void
	PP.scale = function( v ){
		this.x *= v ;
		this.y *= v ;
		this.z *= v ;
	};
	
	// public void
	PP.add = function( p ){
		var d = new P( p );
		this.x += d.x ;
		this.y += d.y ;
		this.z += d.z ;
	};
	PP.sub = function( p ){
		var d = new P( p );
		this.x -= d.x ;
		this.y -= d.y ;
		this.z -= d.z ;
	};
	
	// public string
	PP.toString = function(){ return "Point3 : ( "+this.x+" , "+this.y+" , "+this.z+" )"; };
	
	/****************************** SET_METHOD - E N D ******************************/
	
} setBasicMember__Point3__();


