PageRenderTime 43ms CodeModel.GetById 2ms app.highlight 33ms RepoModel.GetById 2ms app.codeStats 0ms

/src/org/mt4j/util/math/Vector3D.java

http://mt4j.googlecode.com/
Java | 1103 lines | 381 code | 118 blank | 604 comment | 34 complexity | cf6d0dced76205a50442e321441fb772 MD5 | raw file
   1/***********************************************************************
   2 * mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
   3 *  
   4 *   This program is free software: you can redistribute it and/or modify
   5 *   it under the terms of the GNU General Public License as published by
   6 *   the Free Software Foundation, either version 3 of the License, or
   7 *   (at your option) any later version.
   8 *
   9 *   This program is distributed in the hope that it will be useful,
  10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 *   GNU General Public License for more details.
  13 *
  14 *   You should have received a copy of the GNU General Public License
  15 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16 *
  17 ***********************************************************************/
  18package org.mt4j.util.math;
  19
  20import java.awt.Point;
  21
  22
  23/**
  24 * ************************************************
  25 * Homogenous 3D vector class with 4 components, X, Y, Z and W.
  26 * 
  27 * @author Christopher Ruff
  28 * ************************************************
  29 */
  30public class Vector3D {
  31	
  32	/** The w. */
  33	public float x, y, z, w;
  34	
  35	/** The type. */
  36	private transient int type;
  37	
  38	/** The Constant VECTOR. */
  39	public static final int VECTOR 			= 0;
  40	
  41	/** The Constant VERTEX. */
  42	public static final int VERTEX 			= 1;
  43	
  44	/** The Constant BEZIERVERTEX. */
  45	public static final int BEZIERVERTEX 	= 2;
  46	
  47	/** Zero vector (0,0,0). */
  48	public static final Vector3D ZERO_VECTOR = new Vector3D(0,0,0);
  49
  50    /** Defines positive X axis. */
  51    public static final Vector3D X_AXIS = new Vector3D(1, 0, 0);
  52
  53    /** Defines positive Y axis. */
  54    public static final Vector3D Y_AXIS = new Vector3D(0, 1, 0);
  55
  56    /** Defines positive Z axis. */
  57    public static final Vector3D Z_AXIS = new Vector3D(0, 0, 1);
  58
  59
  60	
  61	/**
  62	 * Instantiates a new vector3 d.
  63	 */
  64	public Vector3D() {
  65		this(0,0,0,1);
  66	}
  67	
  68	/**
  69	 * Instantiates a new vector3 d.
  70	 * 
  71	 * @param x the x
  72	 * @param y the y
  73	 */
  74	public Vector3D(float x, float y){
  75		this(x,y,0);
  76	}
  77	
  78	/**
  79	 * Instantiates a new vector3 d.
  80	 * 
  81	 * @param x the x
  82	 * @param y the y
  83	 * @param z the z
  84	 */
  85	public Vector3D(float x, float y, float z){
  86		this(x,y,z,1);
  87	}
  88	
  89	/**
  90	 * Instantiates a new vector3 d.
  91	 * 
  92	 * @param x the x
  93	 * @param y the y
  94	 * @param z the z
  95	 * @param w the w
  96	 */
  97	public Vector3D(float x, float y, float z, float w){
  98		this.x = x;
  99		this.y = y;
 100		this.z = z;
 101		
 102		this.w = w;
 103		
 104		this.setType(Vector3D.VECTOR);
 105	}
 106    
 107
 108	/**
 109	 * Instantiates a new vector3 d.
 110	 * 
 111	 * @param v the v
 112	 */
 113	public Vector3D(Vector3D v) {
 114		this(v.getX(),v.getY(),v.getZ(),v.getW());
 115	}
 116
 117	
 118	/**
 119	 * Gets the deep vertex array copy.
 120	 * Uses the getCopy() method on each vector.
 121	 * 
 122	 * @param vertices the vertices
 123	 * 
 124	 * @return the deep vertex array copy
 125	 */
 126	public static Vector3D[] getDeepVertexArrayCopy(Vector3D[] vertices){
 127		Vector3D[] copy = new Vector3D[vertices.length];
 128		for (int i = 0; i < vertices.length; i++) {
 129			Vector3D vertex = vertices[i]; 
 130			copy[i] = vertex.getCopy();
 131		}
 132		return copy;
 133	}
 134    
 135    /**
 136     * Applies a transformation on the vector
 137     * defined by the given tranformation matrix.
 138     * 
 139     * @param transformMatrix the transform matrix
 140     */
 141	public void transform(Matrix transformMatrix){
 142		transformMatrix.mult(this);
 143	}
 144	
 145	
 146	//TODO reicht es den W coord des Vectors auf 0 zu setzen?
 147	//FIXME eigentlich sollte man direction vectoren wie normale
 148	//transformieren also mit transformNormal, aber so gehts auch meistens..why?
 149	/**
 150	 * Transforms a direction vector, not a point.
 151	 * Ignores the translation part of the matrix
 152	 * 
 153	 * @param transformMatrix the transform matrix
 154	 */
 155	public void transformDirectionVector(Matrix transformMatrix){
 156		Matrix m = new Matrix(transformMatrix);
 157		m.removeTranslationFromMatrix();
 158		this.transform(m);
 159	}
 160	
 161	/**
 162	 * Transforms a normal or direction vector.
 163	 * This is done by multiplying the vector with the
 164	 * inverse transpose of the matrix.
 165	 * <p>
 166	 * <strong>NOTE</strong>: this is not cheap because a new matrix is created (copied)
 167	 * inverted and then transposed.<p>
 168	 * (If you can supply a precomputed inverted matrix yourself, write
 169	 * yourself a method that doesent do the invert() call :))
 170	 * 
 171	 * @param transformMatrix the transform matrix
 172	 */
 173	public void transformNormal(Matrix transformMatrix){
 174		Matrix inverse = transformMatrix.invert();
 175//		this.setW(0);
 176		try {
 177			Matrix transpose = inverse.transpose();
 178			transpose.mult(this,this);
 179		} catch (Exception e) {
 180			e.printStackTrace();
 181		}
 182	}
 183	
 184	/**
 185	 * Multiplicates all Vector3D of the Vector3D array with the given
 186	 * transformation matrix, thus transforming them.
 187	 * Make a deepcopy of the vectors first if you dont want the originals being altered!
 188	 * 
 189	 * @param transformMatrix the transform matrix
 190	 * @param points the points
 191	 * 
 192	 * @return the transformed vector array
 193	 */
 194	public static Vector3D[] transFormArrayLocal(Matrix transformMatrix, Vector3D[] points){
 195		for (Vector3D v : points)
 196			v.transform(transformMatrix);
 197		return points;
 198	}
 199	
 200	
 201	/**
 202	 * Translate.
 203	 * 
 204	 * @param directionVector the direction vector
 205	 */
 206	public void translate(Vector3D directionVector){
 207		this.transform(Matrix.getTranslationMatrix(directionVector.getX(), directionVector.getY(), directionVector.getZ()));
 208	}
 209	
 210	/**
 211	 * translates an array of Vector3D by the given amounts in the directionvector.
 212	 * 
 213	 * @param inputArray the input array
 214	 * @param directionVector the direction vector
 215	 * 
 216	 * @return the vector3 d[]
 217	 */
 218	public static Vector3D[] translateVectorArray(Vector3D[] inputArray, Vector3D directionVector){
 219		return Vector3D.transFormArrayLocal(Matrix.getTranslationMatrix(directionVector.getX(), directionVector.getY(), directionVector.getZ())
 220				, inputArray);
 221	}
 222	
 223	
 224	/**
 225	 * Rotate x.
 226	 * 
 227	 * @param rotationPoint the rotation point
 228	 * @param degree the degree
 229	 */
 230	public void rotateX(Vector3D rotationPoint, float degree ){
 231		this.transform(Matrix.getXRotationMatrix(rotationPoint, degree));
 232	}
 233	
 234	/**
 235	 * rotates the Vector3D array around the rotationpoint by the given degree.
 236	 * 
 237	 * @param rotationPoint the rotation point
 238	 * @param degree the degree
 239	 * @param inputArray the input array
 240	 * 
 241	 * @return the rotated vector3D array
 242	 */
 243	public static Vector3D[] rotateXVectorArray(Vector3D[] inputArray, Vector3D rotationPoint, float degree ){
 244		return Vector3D.transFormArrayLocal(Matrix.getXRotationMatrix(rotationPoint, degree),inputArray);
 245	}
 246	
 247	
 248	
 249	/**
 250	 * Rotate y.
 251	 * 
 252	 * @param rotationPoint the rotation point
 253	 * @param degree the degree
 254	 */
 255	public void rotateY(Vector3D rotationPoint, float degree ){
 256		this.transform(Matrix.getYRotationMatrix(rotationPoint, degree));
 257	}
 258	
 259	
 260	/**
 261	 * rotates the Vector3D array around the rotationpoint by the given degree.
 262	 * 
 263	 * @param rotationPoint the rotation point
 264	 * @param degree the degree
 265	 * @param inputArray the input array
 266	 * 
 267	 * @return the rotated vector3D array
 268	 */
 269	public static Vector3D[] rotateYVectorArray(Vector3D[] inputArray, Vector3D rotationPoint, float degree ){
 270		return Vector3D.transFormArrayLocal(Matrix.getYRotationMatrix(rotationPoint, degree), inputArray);
 271	}
 272	
 273	
 274	/**
 275	 * Rotate z.
 276	 * 
 277	 * @param rotationPoint the rotation point
 278	 * @param degree the degree
 279	 */
 280	public void rotateZ(Vector3D rotationPoint, float degree ){
 281		this.transform(Matrix.getZRotationMatrix(rotationPoint, degree));
 282	}
 283	
 284	
 285	/**
 286	 * Rotates the vector by the given angle around the X axis.
 287	 * 
 288	 * @param theta the theta
 289	 * 
 290	 * @return itself
 291	 */
 292	public final Vector3D rotateX(float theta) {
 293		float co = (float) Math.cos(theta);
 294		float si = (float) Math.sin(theta);
 295		float zz = co * z - si * y;
 296		y = si * z + co * y;
 297		z = zz;
 298		return this;
 299	}
 300
 301	/**
 302	 * Rotates the vector by the given angle around the Y axis.
 303	 * 
 304	 * @param theta the theta
 305	 * 
 306	 * @return itself
 307	 */
 308	public final Vector3D rotateY(float theta) {
 309		float co = (float) Math.cos(theta);
 310		float si = (float) Math.sin(theta);
 311		float xx = co * x - si * z;
 312		z = si * x + co * z;
 313		x = xx;
 314		return this;
 315	}
 316
 317	/**
 318	 * Rotates the vector by the given angle around the Z axis.
 319	 * RADIANS EXPECTED!
 320	 * @param theta the theta
 321	 * 
 322	 * @return itself
 323	 */
 324	public final Vector3D rotateZ(float theta) {
 325//		/*
 326		float co = (float) Math.cos(theta);
 327		float si = (float) Math.sin(theta);
 328		float xx = co * x - si * y;
 329		y = si * x + co * y;
 330		x = xx;
 331		return this;
 332//		*/
 333	}
 334
 335	/**
 336	 * rotates the Vector3D array around the rotationpoint by the given degree.
 337	 * 
 338	 * @param rotationPoint the rotation point
 339	 * @param degree the degree
 340	 * @param inputArray the input array
 341	 * 
 342	 * @return the rotated vector3D array
 343	 */
 344	public static Vector3D[] rotateZVectorArray(Vector3D[] inputArray, Vector3D rotationPoint, float degree ){
 345		return Vector3D.transFormArrayLocal(Matrix.getZRotationMatrix(rotationPoint, degree), inputArray);
 346	}
 347
 348	
 349	/**
 350	 * Scale the vector by factor.
 351	 * 
 352	 * @param scalar the scalar
 353	 * 
 354	 * @return the vector after scaling
 355	 */   
 356    public Vector3D scaleLocal(float scalar) {
 357    	this.setXYZ(this.x * scalar, this.y * scalar, this.z * scalar ) ;
 358    	return this;
 359    }
 360    
 361    public Vector3D divideLocal(float scalar) {
 362        scalar = 1f/scalar;
 363        x *= scalar;
 364        y *= scalar;
 365        z *= scalar;
 366        return this;
 367    }
 368
 369    
 370    
 371    /**
 372     * Gets the scaled.
 373     * 
 374     * @param scalar the scalar
 375     * 
 376     * @return the scaled
 377     * 
 378     * a new scaled vector
 379     */
 380    public Vector3D getScaled(float scalar) {
 381    	return new Vector3D(this.x * scalar, this.y * scalar, this.z * scalar);
 382    }
 383    
 384	/**
 385	 * scales the Vector3D[] around the scalingpoint by the given factor evenly in the X and Y direction.
 386	 * 
 387	 * @param inputArray the input array
 388	 * @param scalingPoint the scaling point
 389	 * @param factor the factor
 390	 * 
 391	 * @return the resulting vector array
 392	 */
 393	public static Vector3D[] scaleVectorArray(Vector3D[] inputArray, Vector3D scalingPoint, float factor) {
 394		return Vector3D.transFormArrayLocal(Matrix.getScalingMatrix(scalingPoint, factor,factor,factor), inputArray); 
 395	}
 396	
 397	/**
 398	 * scales the Vector3D[] around the scalingpoint by the factors given for each dimension.
 399	 * 
 400	 * @param inputArray the input array
 401	 * @param scalingPoint the scaling point
 402	 * @param X the x
 403	 * @param Y the y
 404	 * @param Z the z
 405	 * 
 406	 * @return the resulting vector array
 407	 */
 408	public static Vector3D[] scaleVectorArray(Vector3D[] inputArray, Vector3D scalingPoint, float X, float Y, float Z) {
 409		return Vector3D.transFormArrayLocal(Matrix.getScalingMatrix(scalingPoint, X, Y, Z), inputArray); 
 410	}
 411	
 412	
 413	/**
 414	 * Add a vector to this vector.
 415	 * 
 416	 * @param v the v
 417	 * 
 418	 * @return the vector after the addition
 419	 */   
 420    public Vector3D addLocal(Vector3D v) {
 421    	this.setX(x + v.getX());
 422    	this.setY(y + v.getY());
 423    	this.setZ(z + v.getZ());
 424    	return this;
 425    }
 426    
 427    /**
 428     * Gets the added.
 429     * 
 430     * @param v the v
 431     * 
 432     * @return an new Vector with the result of the addition
 433     */
 434    public Vector3D getAdded(Vector3D v){
 435    	return new Vector3D(x + v.getX() , y + v.getY(), z + v.getZ());
 436    }
 437    
 438    /**
 439     * NOTE: texture coordinates of the calling vector are kept.
 440     * 
 441     * @param v the v
 442     * 
 443     * @return an new Vector with the result of the subtraction
 444     */
 445    public Vector3D getSubtracted(Vector3D v){
 446    	return new Vector3D(x - v.getX() , y - v.getY(), z - v.getZ());
 447    }
 448    
 449    
 450    /**
 451     * Subtract a vector from this vector.
 452     * 
 453     * @param v the v
 454     * 
 455     * @return TODO
 456     */   
 457    public Vector3D subtractLocal(Vector3D v) {
 458    	this.setX(x - v.getX());
 459    	this.setY(y - v.getY());
 460    	this.setZ(z - v.getZ());
 461    	return this;
 462    }
 463	
 464    /**
 465     * Scales vector uniformly by factor -1 ( v = -v ), overrides coordinates
 466     * with result.
 467     * 
 468     * @return itself
 469     */
 470    public Vector3D invertLocal() {
 471            x *= -1;
 472            y *= -1;
 473            z *= -1;
 474            return this;
 475    }
 476
 477    /**
 478     * Scales vector uniformly by factor -1 ( v = -v ), overrides coordinates
 479     * with result.
 480     * 
 481     * @return itself
 482     */
 483    public Vector3D getInverted() {
 484    	return new Vector3D(x*-1, y*-1, z*-1);
 485    }
 486    
 487    
 488    
 489    /**
 490     * Interpolates the vector towards the given target vector, using linear
 491     * interpolation.
 492     * 
 493     * @param v target vector
 494     * @param f interpolation factor (should be in the range 0..1)
 495     * 
 496     * @return result as new vector
 497     */
 498    public final Vector3D getInterpolatedTo(Vector3D v, float f) {
 499            return new Vector3D(x + (v.x - x) * f, y + (v.y - y) * f, z + (v.z - z)
 500                            * f);
 501    }
 502    
 503    
 504	/**
 505	 * Copy the vector.
 506	 * 
 507	 * @return      a copy of the vector
 508	 */
 509    public Vector3D getCopy() {
 510    	return new Vector3D(x, y, z, w);
 511    }
 512    
 513    
 514    /**
 515     * Calculate the magnitude (length) of the vector.
 516     * 
 517     * @return      the magnitude of the vector
 518     */
 519    public float length() {
 520        return (float) Math.sqrt(x*x + y*y + z*z);
 521    }
 522    
 523    /**
 524     * Calculates only the squared magnitude/length of the vector. Useful for
 525     * inverse square law applications and/or for speed reasons or if the real
 526     * eucledian distance is not required (e.g. sorting).
 527     * 
 528     * @return squared magnitude (x^2 + y^2 + z^2)
 529     */
 530    public float lengthSquared() {
 531            return x * x + y * y + z * z;
 532    }
 533
 534    
 535    /**
 536     * Calculate the cross product with another vector. And returns
 537     * a new vector as the result.
 538     * 
 539     * @param v the v
 540     * 
 541     * @return  the cross product, a new vector
 542     */     
 543    public Vector3D getCross(Vector3D v) {
 544        float crossX = y * v.getZ() - v.getY() * z;
 545        float crossY = z * v.getX() - v.getZ() * x;
 546        float crossZ = x * v.getY() - v.getX() * y;
 547        return new Vector3D(crossX,crossY,crossZ);
 548    }
 549    
 550    /**
 551     * Calcs the cross and sets the new values to this vector.
 552     * 
 553     * @param v the v
 554     * 
 555     * @return the Vector after the cross operation
 556     */
 557    public Vector3D crossLocal(Vector3D v) {
 558        float crossX = y * v.getZ() - v.getY() * z;
 559        float crossY = z * v.getX() - v.getZ() * x;
 560        float crossZ = x * v.getY() - v.getX() * y;
 561        this.setXYZ(crossX, crossY, crossZ);
 562        return this;
 563    }
 564    
 565    /**
 566     * Calculate the dot product with another vector.
 567     * 
 568     * @param v the v
 569     * 
 570     * @return  the dot product
 571     */     
 572    public float dot(Vector3D v) {
 573        return this.x * v.x + this.y * v.y + this.z * v.z;
 574    } //(x * v.x + y * v.y + z * v.z);
 575    
 576    /**
 577     * Normalize the vector to length 1 (make it a unit vector).
 578     * 
 579     * @return the same vector after normalization
 580     */     
 581    public Vector3D normalizeLocal() {
 582//        float m = length();
 583//        if (m > 0) {
 584//        	this.setX(x / m);
 585//        	this.setY(y / m);
 586//        	this.setZ(z / m);
 587//        }
 588        float length = length();
 589        if (length != 0) {
 590        	float scalar = length;
 591        	 scalar = 1f/scalar;
 592             x *= scalar;
 593             y *= scalar;
 594             z *= scalar;
 595        }
 596        return this;
 597    }
 598    
 599    /**
 600     * Normalize the vector to length 1 (make it a unit vector).
 601     * 
 602     * @return a NEW vector after normalization of this vector
 603     */     
 604    public Vector3D getNormalized() {
 605    	Vector3D n = this;
 606        float length = length();
 607        if (length != 0) {
 608        	float scalar = length;
 609        	 scalar = 1f/scalar;
 610             n = new Vector3D(this.x*scalar, this.y*scalar, this.z*scalar);
 611        }
 612        return n;
 613    }
 614    
 615    
 616    /**
 617     * Limits the vector to the given length .
 618     * 
 619     * @param lim new maximum magnitude
 620     * @return the limited vector
 621     */
 622    public final Vector3D limitLocal(float lim) {
 623    	if (this.lengthSquared() > lim * lim) {
 624    		normalizeLocal();
 625    		scaleLocal(lim);
 626    	}
 627    	return this;
 628    }
 629    
 630    
 631    /**
 632     * Creates a copy of the vector with its magnitude limited to the length
 633     * given.
 634     * 
 635     * @param lim new maximum magnitude
 636     * 
 637     * @return result as new vector
 638     */
 639    public final Vector3D getLimited(float lim) {
 640    	if (this.lengthSquared() > lim * lim) {
 641    		Vector3D norm = this.getCopy();
 642    		norm.normalizeLocal();
 643    		norm.scaleLocal(lim);
 644    		return norm;
 645    	}
 646    	return new Vector3D(this);
 647    }
 648    
 649
 650    /**
 651     * Rotates the vector around the giving axis.
 652     * 
 653     * @param axis rotation axis vector
 654     * @param theta rotation angle (in radians)
 655     * 
 656     * @return itself
 657     */
 658    public final Vector3D rotateAroundAxisLocal(Vector3D axis, float theta) {
 659    	float ux = axis.x * x;
 660    	float uy = axis.x * y;
 661    	float uz = axis.x * z;
 662    	float vx = axis.y * x;
 663    	float vy = axis.y * y;
 664    	float vz = axis.y * z;
 665    	float wx = axis.z * x;
 666    	float wy = axis.z * y;
 667    	float wz = axis.z * z;
 668    	double si = Math.sin(theta);
 669    	double co = Math.cos(theta);
 670    	float xx = (float) (axis.x
 671    			* (ux + vy + wz)
 672    			+ (x * (axis.y * axis.y + axis.z * axis.z) - axis.x * (vy + wz))
 673    			* co + (-wy + vz) * si);
 674    	float yy = (float) (axis.y
 675    			* (ux + vy + wz)
 676    			+ (y * (axis.x * axis.x + axis.z * axis.z) - axis.y * (ux + wz))
 677    			* co + (wx - uz) * si);
 678    	float zz = (float) (axis.z
 679    			* (ux + vy + wz)
 680    			+ (z * (axis.x * axis.x + axis.y * axis.y) - axis.z * (ux + vy))
 681    			* co + (-vx + uy) * si);
 682    	x = xx;
 683    	y = yy;
 684    	z = zz;
 685    	return this;
 686    }
 687
 688
 689    /**
 690     * Calculate the Euclidean distance between two points (considering a point as a vector object).
 691     * 
 692     * @param v2 another vector
 693     * @param v1 the v1
 694     * 
 695     * @return the Euclidean distance between v1 and v2
 696     */ 
 697    public static float distance (Vector3D v1, Vector3D v2) {
 698    	float dx = v1.getX() - v2.getX();
 699    	float dy = v1.getY() - v2.getY();
 700    	float dz = v1.getZ() - v2.getZ();
 701    	return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
 702    }
 703    
 704    
 705    /**
 706     *  Calculate the Euclidean distance between two points (considering a point as a vector object).
 707     * 
 708     * @param v2 the v2
 709     * 
 710     * @return the float
 711     */
 712    public float distance(Vector3D v2){
 713    	float dx = this.getX() - v2.getX();
 714    	float dy = this.getY() - v2.getY();
 715    	float dz = this.getZ() - v2.getZ();
 716    	return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
 717    }
 718    
 719    
 720    /**
 721     * Calculate the Euclidean distance between two points (considering a point as a vector object).
 722     * 
 723     * @param v2 another vector
 724     * @param v1 the v1
 725     * 
 726     * @return the Euclidean distance between v1 and v2
 727     */ 
 728    public static float distance2D (Vector3D v1, Vector3D v2) {
 729    	float dx = v1.getX() - v2.getX();
 730    	float dy = v1.getY() - v2.getY();
 731    	return (float) Math.sqrt(dx*dx + dy*dy );
 732    }
 733    
 734    /**
 735     * Calculate the Euclidean distance between two points (considering a point as a vector object).
 736     * Disregards the Z component of the vectors and is thus a little faster.
 737     * 
 738     * @param v2 another vector
 739     * 
 740     * @return the Euclidean distance between this and v2
 741     */ 
 742    public float distance2D (Vector3D v2) {
 743    	float dx = this.getX() - v2.getX();
 744    	float dy = this.getY() - v2.getY();
 745    	return (float) Math.sqrt(dx*dx + dy*dy );
 746    }
 747
 748    /**
 749     * Calculate the Euclidean distance between two points (considering a point as a vector object).
 750     * 
 751     * @param v2 another vector
 752     * @param v1 the v1
 753     * 
 754     * @return the Euclidean distance between v1 and v2 squared
 755     */ 
 756    public static float distanceSquared (Vector3D v1, Vector3D v2) {
 757    	if (v2 != null) {
 758    		float dx = v1.x - v2.x;
 759    		float dy = v1.y - v2.y;
 760    		float dz = v1.z - v2.z;
 761    		return dx * dx + dy * dy + dz * dz;
 762    	} else {
 763    		return Float.NaN;
 764    	}
 765    }
 766
 767    /**
 768     * Calculate the angle between two vectors, using the dot product.
 769     * 
 770     * @param v2 another vector
 771     * @param v1 the v1
 772     * 
 773     * @return the angle between the vectors in radians
 774     */ 
 775//  FIXME this produces an not 0.0 angle for equal vectors sometimes..why?
 776    public static float angleBetween(Vector3D v1, Vector3D v2) {
 777//    	Vector3D v1Copy = v1.getCopy();
 778//    	Vector3D v2Copy = v2.getCopy();
 779//    	
 780//    	v1Copy.normalize();
 781//    	v2Copy.normalize();
 782//    	
 783//    	float dotP = v1Copy.dot(v2Copy);
 784//    	System.out.println("Dot:" + dotP);
 785//    	float theta = (float)Math.acos(dotP);
 786    	
 787//        float dot = v1.dot(v2);
 788//        float theta = FastMath.acos(dot / (v1.length() * v2.length()));
 789//        return theta;
 790    	
 791    	return v1.angleBetween(v2);
 792    }
 793    
 794    /**
 795     * Calculate the angle between two vectors, using the dot product.
 796     * 
 797     * @param v2 another vector
 798     * 
 799     * @return the angle between the vectors in radians
 800     */ 
 801//  FIXME this produces an not 0.0 angle for equal vectors sometimes..why?
 802    public float angleBetween(Vector3D v2) {
 803        float dot = this.dot(v2);
 804        float theta = ToolsMath.acos(dot / (this.length() * v2.length()));
 805        return theta;
 806    }
 807	
 808	/**
 809	 * sets a new X coordinate value for the vector.
 810	 * 
 811	 * @param x the x
 812	 */
 813	public void setX(float x) {
 814		this.x = x;
 815	}
 816
 817	/**
 818	 * sets a new Y coordinate value for the vector.
 819	 * 
 820	 * @param y the y
 821	 */
 822	public void setY(float y) {
 823		this.y = y;
 824	}
 825
 826	/**
 827	 * sets a new Z coordinate value for the vector.
 828	 * 
 829	 * @param z the z
 830	 */
 831	public void setZ(float z) {
 832		this.z = z;
 833	}
 834	
 835	
 836	/**
 837	 * sets new values for the vector.
 838	 * 
 839	 * @param x the x
 840	 * @param y the y
 841	 * @param z the z
 842	 */
 843	public void setXYZ(float x, float y, float z){
 844		this.x = x;
 845		this.y = y;
 846		this.z = z;
 847	}
 848	
 849	/**
 850	 * sets new values for the vector.
 851	 * 
 852	 * @param x the x
 853	 * @param y the y
 854	 * @param z the z
 855	 * @param w the w
 856	 */
 857	public void setXYZW(float x, float y, float z, float w){
 858		this.setXYZ(x, y, z);
 859		this.w = w;
 860	}
 861		
 862	/**
 863	 * Converts the 3D homogenous vector to a 2D jawa.awt.point, throwing away the Z-Value
 864	 * 
 865	 * @return the point
 866	 */
 867    public Point getJava2DPoint(){ 
 868			return new Point(Math.round(x),Math.round(y));
 869	}
 870    
 871	/**
 872	 * Gets the y.
 873	 * 
 874	 * @return the Y value of the 3D Vector
 875	 */
 876    public float getY(){ 
 877		return y;
 878    }
 879    
 880    /**
 881     * Gets the z.
 882     * 
 883     * @return the Z value of the 3D Vector
 884     */
 885    public float getZ(){ 
 886		return z;
 887    }
 888    
 889    /**
 890     * Gets the x.
 891     * 
 892     * @return the X value of the 3D Vector
 893     */
 894    public float getX(){ 
 895		return x;
 896    }
 897
 898	/**
 899	 * Gets the w.
 900	 * 
 901	 * @return the W
 902	 * 
 903	 * the W value of the 3D Vector
 904	 */
 905	public float getW() {
 906		return w;
 907	}
 908
 909	/**
 910	 * Sets the w.
 911	 * 
 912	 * @param w the new w
 913	 */
 914	public void setW(float w) {
 915		this.w = w;
 916	}
 917	
 918	/**
 919	 * Sets the.
 920	 * 
 921	 * @param i the i
 922	 * @param value the value
 923	 */
 924	public void set(int i, float value){
 925		if (i == 0)
 926			x = value;
 927		else if(i == 1)
 928			y = value;
 929		else if(i == 2)
 930			z = value;
 931		else if(i == 3)
 932			w = value;
 933		else{ 
 934			System.err.println("illegal vector dimension");
 935		}
 936	}
 937	///
 938	
 939	/**
 940	 * Returns an integer in case of:
 941	 * <br>VECTOR = 0;
 942	 * <br>VERTEX = 1;
 943	 * <br>BEZIERVERTEX = 2;.
 944	 * 
 945	 * @return the type
 946	 * 
 947	 * the integer identifying this object
 948	 */
 949	public int getType() {
 950		return type;
 951	}
 952
 953	/**
 954	 * Sets the type. This should only be called
 955	 * by extending classes to determine their type.
 956	 * 
 957	 * @param type the type
 958	 */
 959	protected void setType(int type) {
 960		this.type = type;
 961	}
 962
 963	/**
 964	 * Checks if the two vectors have the same components (XYZW).
 965	 * <br>Does NOT check for object identity equality!
 966	 * 
 967	 * @param vector3D the vector3 d
 968	 * 
 969	 * @return true, if equals vector
 970	 */
 971	public boolean equalsVector(Vector3D vector3D){
 972		return (   this.getX() == vector3D.getX()		
 973				&& this.getY() == vector3D.getY()	
 974				&& this.getZ() == vector3D.getZ()
 975				&& this.getW() == vector3D.getW()
 976		);
 977	}
 978	
 979	/**
 980	 * Checks if the two vectors have the same components (XYZW) in the range of a
 981	 * specified tolerance.
 982	 * <br>Does NOT check for object identity equality!
 983	 * <br>NOTE: checks each component of the vector individually, so the overall difference
 984	 * might be greater than the given tolerance!
 985	 * 
 986	 * @param vec the vec
 987	 * @param tolerance the tolerance
 988	 * 
 989	 * @return true, if equals vector with tolerance
 990	 */
 991	public boolean equalsVectorWithTolerance(Vector3D vec, float tolerance){
 992		return (   Math.abs(this.getX() - vec.getX()) <= tolerance		
 993				&& Math.abs(this.getY() - vec.getY()) <= tolerance
 994				&& Math.abs(this.getZ() - vec.getZ()) <= tolerance
 995				&& Math.abs(this.getW() - vec.getW()) <= tolerance
 996		);
 997	}
 998	
 999	
1000	 /**
1001 	 * Saves this Vector3f into the given float[] object.
1002 	 * 
1003 	 * @param floats The float[] to take this Vector3f. If null, a new float[3] is
1004 	 * created.
1005 	 * 
1006 	 * @return The array, with X, Y, Z float values in that order
1007 	 */
1008    public float[] toArray(float[] floats) {
1009        if (floats == null) {
1010            floats = new float[3];
1011        }
1012        floats[0] = x;
1013        floats[1] = y;
1014        floats[2] = z;
1015        return floats;
1016    }
1017
1018	/**
1019	 * Sets the values of another vector.
1020	 * 
1021	 * @param otherVector the new values
1022	 * 
1023	 * @return the vector3 d
1024	 */
1025	public Vector3D setValues(Vector3D otherVector){
1026		this.x = otherVector.x;
1027		this.y = otherVector.y;
1028		this.z = otherVector.z;
1029		this.w = otherVector.w;
1030		return this;
1031	}
1032    
1033    /* (non-Javadoc)
1034     * @see java.lang.Object#toString()
1035     */
1036    public String toString(){
1037    	return " X:" + this.getX() + " Y:" + this.getY() + " Z:" + this.getZ() + " W:" + this.getW();
1038    }
1039    
1040//    //TODO CHECK IF THIS WORKS; TOO
1041//    /*
1042//      /**
1043//     * Transform the provided vector by the matrix and place it back in
1044//     * the vector.
1045//     *
1046//     * @param vec The vector to be transformed
1047//     * @param mat The matrix to do the transforming with
1048//     * @param out The vector to be put the result in
1049//     */
1050//    private void transform(Tuple3f vec, Matrix4f mat, Tuple3d out)
1051//    {
1052//        float a = vec.x;
1053//        float b = vec.y;
1054//        float c = vec.z;
1055//
1056//        out.x = mat.m00 * a + mat.m01 * b + mat.m02 * c + mat.m03;
1057//        out.y = mat.m10 * a + mat.m11 * b + mat.m12 * c + mat.m13;
1058//        out.z = mat.m20 * a + mat.m21 * b + mat.m22 * c + mat.m23;
1059//    }
1060//
1061//    /**
1062//     * Transform the provided vector by the matrix and place it back in
1063//     * the vector. The fourth element is assumed to be zero for normal
1064//     * transformations.
1065//     *
1066//     * @param vec The vector to be transformed
1067//     * @param mat The matrix to do the transforming with
1068//     * @param out The vector to be put the result in
1069//     */
1070//    private void transformNormal(Tuple3d vec, Matrix4f mat, Tuple3d out)
1071//    {
1072//        float a = (float)vec.x;
1073//        float b = (float)vec.y;
1074//        float c = (float)vec.z;
1075//
1076//        out.x = mat.m00 * a + mat.m01 * b + mat.m02 * c;
1077//        out.y = mat.m10 * a + mat.m11 * b + mat.m12 * c;
1078//        out.z = mat.m20 * a + mat.m21 * b + mat.m22 * c;
1079//    }
1080//
1081//    /**
1082//     * Transform the provided vector by the matrix and place it back in
1083//     * the vector. The fourth element is assumed to be zero for normal
1084//     * transformations.
1085//     *
1086//     * @param vec The vector to be transformed
1087//     * @param mat The matrix to do the transforming with
1088//     * @param out The vector to be put the result in
1089//     */
1090//    private void transformNormal(Tuple3f vec, Matrix4f mat, Tuple3d out)
1091//    {
1092//        float a = vec.x;
1093//        float b = vec.y;
1094//        float c = vec.z;
1095//
1096//        out.x = mat.m00 * a + mat.m01 * b + mat.m02 * c;
1097//        out.y = mat.m10 * a + mat.m11 * b + mat.m12 * c;
1098//        out.z = mat.m20 * a + mat.m21 * b + mat.m22 * c;
1099//    }
1100//}
1101//     */
1102    
1103}