/* * $Id$ * * Copyright (C) 2010-2012 Stephane GALLAND. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * This program is free software; you can redistribute it and/or modify */ package org.arakhne.afc.math.geometry.d3.continuous; import static org.arakhne.afc.math.MathConstants.PI; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import org.arakhne.afc.math.AbstractMathTestCase; import org.arakhne.afc.math.geometry.coordinatesystem.CoordinateSystem3D; import org.arakhne.afc.math.geometry.d2.continuous.Vector2f; import org.arakhne.afc.math.geometry.d3.FunctionalVector3D; import org.arakhne.afc.math.geometry.d3.Vector3D; import org.arakhne.afc.math.matrix.Matrix3f; import org.junit.Test; /** * @author $Author: hjaffali$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ @SuppressWarnings("all") public class Vector3fTest extends AbstractMathTestCase { @Test public void testClone() { Vector3f r = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f b = r.clone(); assertNotSame(b, r); assertEpsilonEquals(r.getX(), b.getX()); assertEpsilonEquals(r.getY(), b.getY()); assertEpsilonEquals(r.getZ(), b.getZ()); b.set(r.getX()+1f, r.getY()+1f, r.getZ()+1f); assertNotEpsilonEquals(r.getX(), b.getX()); assertNotEpsilonEquals(r.getY(), b.getY()); assertNotEpsilonEquals(r.getZ(), b.getZ()); } @Test public void angleVector3D() { Vector3f vector = new Vector3f(1,2,0); Vector3f vector2 = new Vector3f(-2,1,0); Vector3f vector3 = new Vector3f(-1,-1,-1); Vector3f vector4 = new Vector3f(1,0,0); assertEpsilonEquals(PI/2f,vector.angle(vector2)); assertEpsilonEquals(Math.acos(-1/Math.sqrt(3)),vector4.angle(vector3)); assertEpsilonEquals(Math.acos(1/Math.sqrt(5)),vector4.angle(vector)); assertEpsilonEquals(PI/2f+Math.acos(1/Math.sqrt(5)),vector4.angle(vector2)); assertEpsilonEquals(0,vector.angle(vector)); } @Test public void dotVector3D() { Vector3f a = new Vector3f(10*this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()*this.random.nextDouble()); Vector3f b = new Vector3f(this.random.nextDouble(),5*this.random.nextDouble(),this.random.nextDouble()); double product = a.getX()*b.getX() + a.getY()*b.getY() + a.getZ()*b.getZ(); assertEpsilonEquals(product,a.dot(b)); } @Test public void mulMatrix3f() { Vector3f vector = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Matrix3f matrix = new Matrix3f(1,2,4,5,1,3,9,-2,1); Vector3D product = new Vector3f(vector.getX()+2*vector.getY()+4*vector.getZ(),5*vector.getX()+vector.getY()+3*vector.getZ(),9*vector.getX()-2*vector.getY()+vector.getZ()); assertTrue(product.equals(vector.mul(matrix))); } @Test public void determinantDoubleDoubleDoubleDoubleDoubleDoubleDoubleDoubleDouble() { double a = this.random.nextDouble()*20; double b = this.random.nextDouble()*20; double c = this.random.nextDouble()*20; double d = this.random.nextDouble()*20; double e = this.random.nextDouble()*20; double f = this.random.nextDouble()*20; double g = this.random.nextDouble()*20; double h = this.random.nextDouble()*20; double i = this.random.nextDouble()*20; Matrix3f matrix = new Matrix3f(a,b,c, d,e,f, g,h,i); Vector3f temp = new Vector3f(); double determinant = a*e*i -a*f*h -b*d*i + b*f*g + c*d*h - c*e*g; assertEpsilonEquals(determinant,FunctionalVector3D.determinant(a, b, c, d, e, f, g, h, i)); } @Test public void perpVector3D() { // TODO still remain problem here Vector3f v1 = new Vector3f(this.random.nextDouble(), this.random.nextDouble(), this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(), this.random.nextDouble(), this.random.nextDouble()); double dotProduct = v1.dot(v2); double perpProduct = Math.abs(v1.perp(v2)); double angle = v1.angle(v2); assertEpsilonEquals(Math.tan(angle),perpProduct/dotProduct); } @Test public void signedAngleDoubleDoubleDoubleDoubleDoubleDouble() { Vector3f v1 = new Vector3f(this.random.nextDouble()*50, this.random.nextDouble()*50, this.random.nextDouble()*50); Vector3f v2 = new Vector3f(this.random.nextDouble()*50, this.random.nextDouble()*50, this.random.nextDouble()*50); assertEpsilonEquals( 0.f, FunctionalVector3D.signedAngle(v1.getX(),v1.getY(),v1.getZ(),v1.getX(),v1.getY(),v1.getZ())); assertEpsilonEquals( 0.f, FunctionalVector3D.signedAngle(v2.getX(),v2.getY(),v2.getZ(),v2.getX(),v2.getY(),v2.getZ())); double sAngle1 = FunctionalVector3D.signedAngle(v1.getX(),v1.getY(),v1.getZ(),v2.getX(),v2.getY(),v2.getZ()); double sAngle2 = FunctionalVector3D.signedAngle(v2.getX(),v2.getY(),v2.getZ(),v1.getX(),v1.getY(),v1.getZ()); assertEpsilonEquals(-sAngle1, sAngle2); assertEpsilonEquals(v1.angle(v2), Math.abs(sAngle1)); assertEpsilonEquals(v2.angle(v1), Math.abs(sAngle2)); } @Test public void crossVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f cross1 = new Vector3f(-v1.getZ()*v2.getY()+v1.getY()*v2.getZ(),v1.getZ()*v2.getX()-v1.getX()*v2.getZ(),-v1.getY()*v2.getX()+v1.getX()*v2.getY()); assertTrue(cross1.equals(v1.cross(v2))); cross1.negate(); assertTrue(cross1.equals(v2.cross(v1))); } @Test public void crossVector3DVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f cross1 = new Vector3f(-v1.getZ()*v2.getY()+v1.getY()*v2.getZ(),v1.getZ()*v2.getX()-v1.getX()*v2.getZ(),-v1.getY()*v2.getX()+v1.getX()*v2.getY()); Vector3f cross2 = new Vector3f(); cross2.cross(v1, v2); assertTrue(cross1.equals(cross2)); cross1.negate(); cross2.cross(v2, v1); assertTrue(cross1.equals(cross2)); cross1.negate(); } @Test public void crossLeftHandVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f cross1 = new Vector3f(v1.getZ()*v2.getY()-v1.getY()*v2.getZ(),-v1.getZ()*v2.getX()+v1.getX()*v2.getZ(),v1.getY()*v2.getX()-v1.getX()*v2.getY()); assertTrue(cross1.equals(v1.crossLeftHand(v2))); cross1.negate(); assertTrue(cross1.equals(v2.crossLeftHand(v1))); } @Test public void crossLeftHandVector3DVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f cross1 = new Vector3f(v1.getZ()*v2.getY()-v1.getY()*v2.getZ(),-v1.getZ()*v2.getX()+v1.getX()*v2.getZ(),v1.getY()*v2.getX()-v1.getX()*v2.getY()); Vector3f cross2 = new Vector3f(); cross2.crossLeftHand(v1, v2); assertTrue(cross1.equals(cross2)); cross1.negate(); cross2.crossLeftHand(v2, v1); assertTrue(cross1.equals(cross2)); } @Test public void crossRightHandVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f cross1 = new Vector3f(-v1.getZ()*v2.getY()+v1.getY()*v2.getZ(),v1.getZ()*v2.getX()-v1.getX()*v2.getZ(),-v1.getY()*v2.getX()+v1.getX()*v2.getY()); assertTrue(cross1.equals(v1.crossRightHand(v2))); cross1.negate(); assertTrue(cross1.equals(v2.crossRightHand(v1))); } @Test public void crossRightHandVector3DVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f cross1 = new Vector3f(-v1.getZ()*v2.getY()+v1.getY()*v2.getZ(),v1.getZ()*v2.getX()-v1.getX()*v2.getZ(),-v1.getY()*v2.getX()+v1.getX()*v2.getY()); Vector3f cross2 = new Vector3f(); cross2.crossRightHand(v1, v2); assertTrue(cross1.equals(cross2)); cross1.negate(); cross2.crossRightHand(v2, v1); assertTrue(cross1.equals(cross2)); } @Test public void length() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); double length = Math.sqrt(v1.getX()*v1.getX() + v1.getY()*v1.getY() + v1.getZ()*v1.getZ()); assertEpsilonEquals(length,v1.length()); } @Test public void lengthSquared() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); double lengthSquared = (v1.getX()*v1.getX() + v1.getY()*v1.getY() + v1.getZ()*v1.getZ()); assertEpsilonEquals(lengthSquared,v1.getLengthSquared()); } @Test (expected = ArithmeticException.class) public void normalizeVector3D() { Vector3f vector = new Vector3f(1,2,0); Vector3f vector2 = new Vector3f(0,0,0); Vector3f vector3 = new Vector3f(-1,1,0); vector.normalize(vector); assertTrue(vector.equals(new Vector3f((int)(1/Math.sqrt(5)),(int)(2/Math.sqrt(5)),0))); vector.normalize(vector2); vector.normalize(vector3); assertTrue(vector.equals(new Vector3f((int)(-1/Math.sqrt(2)),(int)(1/Math.sqrt(2)),0))); } @Test (expected = ArithmeticException.class) public void normalize() { Vector3f vector = new Vector3f(1,2,0); Vector3f vector2 = new Vector3f(0,0,0); Vector3f vector3 = new Vector3f(-1,1,0); vector.normalize(); vector2.normalize(); vector3.normalize(); assertTrue(vector.equals(new Vector3f(1/Math.sqrt(5),2/Math.sqrt(5),0))); assertTrue(vector3.equals(new Vector3f(-1/Math.sqrt(2),1/Math.sqrt(2),0))); } @Test public void turnVectorVector3DDouble() { // TODO still remain problem here Vector3f vector = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f axis = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); axis.normalize(); double angle = this.random.nextDouble(); Matrix3f turn = new Matrix3f( axis.getX()*axis.getX()+(1-axis.getX()*axis.getX())*Math.cos(angle), axis.getX()*axis.getY()*(1-Math.cos(angle))-axis.getZ()*Math.sin(angle), axis.getX()*axis.getZ()*(1-Math.cos(angle))+axis.getY()*Math.sin(angle), axis.getX()*axis.getY()*(1-Math.cos(angle))+axis.getZ()*Math.sin(angle), axis.getY()*axis.getY()+(1-axis.getY()*axis.getY())*Math.cos(angle), axis.getY()*axis.getZ()*(1-Math.cos(angle))-axis.getX()*Math.sin(angle), axis.getX()*axis.getZ()*(1-Math.cos(angle))-axis.getY()*Math.sin(angle), axis.getY()*axis.getZ()*(1-Math.cos(angle))+axis.getX()*Math.sin(angle), axis.getZ()*axis.getZ()+(1-axis.getZ()*axis.getZ())*Math.cos(angle)); Vector3f vectorTurned = vector.mul(turn); vector.turnVector(axis, angle); assertEpsilonEquals(vector.length(),vectorTurned.length()); assertEpsilonEquals(vector.signedAngle(new Vector3f(1,0,0)),vectorTurned.signedAngle(new Vector3f(1,0,0))); assertTrue(vector.equals(vectorTurned)); } @Test public void addVector3DVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f sum = new Vector3f(v1.getX()+v2.getX(),v1.getY()+v2.getY(),v1.getZ()+v2.getZ()); v1.add(v1, v2); assertTrue(sum.equals(v1)); } @Test public void addVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f sum = new Vector3f(v1.getX()+v2.getX(),v1.getY()+v2.getY(),v1.getZ()+v2.getZ()); v1.add(v2); assertTrue(sum.equals(v1)); } @Test public void scaleAddIntVector3DVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); int i = this.random.nextInt(); Vector3f scalarSum = new Vector3f(i*v1.getX()+v2.getX(),i*v1.getY()+v2.getY(),i*v1.getZ()+v2.getZ()); v1.scaleAdd(i,v1, v2); assertTrue(scalarSum.equals(v1)); } @Test public void scaleAddDoubleVector3DVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); double s = this.random.nextDouble(); Vector3f scalarSum = new Vector3f(s*v1.getX()+v2.getX(),s*v1.getY()+v2.getY(),s*v1.getZ()+v2.getZ()); v1.scaleAdd(s,v1, v2); assertTrue(scalarSum.equals(v1)); } @Test public void scaleAddIntVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); int i = this.random.nextInt(); Vector3f scalarSum = new Vector3f(i*v1.getX()+v2.getX(),i*v1.getY()+v2.getY(),i*v1.getZ()+v2.getZ()); v1.scaleAdd(i,v2); assertTrue(scalarSum.equals(v1)); } @Test public void scaleAddDoubleVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); double s = this.random.nextDouble(); Vector3f scalarSum = new Vector3f(s*v1.getX()+v2.getX(),s*v1.getY()+v2.getY(),s*v1.getZ()+v2.getZ()); v1.scaleAdd(s, v2); assertTrue(scalarSum.equals(v1)); } @Test public void subVector3DVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f sum = new Vector3f(v1.getX()-v2.getX(),v1.getY()-v2.getY(),v1.getZ()-v2.getZ()); v1.sub(v1, v2); assertTrue(sum.equals(v1)); } @Test public void subPoint3DPoint3D() { Point3f v1 = new Point3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Point3f v2 = new Point3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f temp = new Vector3f(); Point3f sum = new Point3f(v1.getX()-v2.getX(),v1.getY()-v2.getY(),v1.getZ()-v2.getZ()); temp.sub(v1, v2); assertTrue(sum.equals(temp)); } @Test public void subVector3D() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f sum = new Vector3f(v1.getX()-v2.getX(),v1.getY()-v2.getY(),v1.getZ()-v2.getZ()); v1.sub(v2); assertTrue(sum.equals(v1)); } @Test public void isUnitVector() { Vector3f vector = new Vector3f(7.15161,6.7545,-9.1516); Vector3f vector2 = new Vector3f(1,1,1); vector.normalize(); vector2.setLength(1); assertTrue(vector.isUnitVector()); assertTrue(vector2.isUnitVector()); assertTrue((new Vector3f(Math.sqrt(2)/2,Math.sqrt(2)/2,0)).isUnitVector()); assertTrue((new Vector3f(1,0,0)).isUnitVector()); } @Test public void isCollinearVectors() { Vector3f v1 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v2 = new Vector3f(this.random.nextDouble(),this.random.nextDouble(),this.random.nextDouble()); Vector3f v3 = new Vector3f(0,0,0); boolean colinear = (v1.getX()/v2.getX()==v1.getY()/v2.getY()) && (v1.getY()/v2.getY()==v1.getZ()/v2.getZ()); assertTrue(v1.isColinear(v3)); assertTrue(colinear == v1.isColinear(v2)); } @Test public void setLength() { Vector3f vector = new Vector3f(this.random.nextDouble(), this.random.nextDouble(), this.random.nextDouble()); Vector3f vector2 = new Vector3f(0,0,0); Vector3f oldVector = vector.clone(); double newLength = this.random.nextDouble(); vector.setLength(newLength); vector2.setLength(newLength); assertEpsilonEquals(vector.angle(oldVector), 0); assertEpsilonEquals(vector.length()*oldVector.length()/newLength,oldVector.length()); assertTrue(vector2.equals(new Vector3f(newLength,0,0))); } }