/* * Copyright (C) 2011-2015, Peter Abeles. All Rights Reserved. * * This file is part of Geometric Regression Library (GeoRegression). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package georegression.geometry; import georegression.misc.GrlConstants; import georegression.struct.point.Point2D_F64; import georegression.struct.point.Point3D_F64; import georegression.struct.point.Vector2D_F64; import georegression.struct.point.Vector3D_F64; import org.ejml.data.DenseMatrix64F; import org.ejml.ops.CommonOps; import org.ejml.ops.MatrixFeatures; import org.ejml.ops.RandomMatrices; import org.junit.Test; import java.util.Random; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * @author Peter Abeles */ public class TestGeometryMath_F64 { Random rand = new Random( 0x33 ); /** * Sees if crossMatrix produces a valid output */ @Test public void crossMatrix_validOut() { double a = 1.1, b = -0.5, c = 2.2; Vector3D_F64 v = new Vector3D_F64( a, b, c ); Vector3D_F64 x = new Vector3D_F64( 7.6, 2.9, 0.5 ); Vector3D_F64 found0 = new Vector3D_F64(); Vector3D_F64 found1 = new Vector3D_F64(); GeometryMath_F64.cross( v, x, found0 ); DenseMatrix64F V = GeometryMath_F64.crossMatrix( a, b, c, null ); GeometryMath_F64.mult( V, x, found1 ); assertEquals( found0.x, found1.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( found0.y, found1.y, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( found0.z, found1.z, GrlConstants.DOUBLE_TEST_TOL ); } /** * Sees if both crossMatrix functions produce the same output */ @Test public void crossMatrix_sameOut() { double a = 1.1, b = -0.5, c = 2.2; Vector3D_F64 v = new Vector3D_F64( a, b, c ); DenseMatrix64F V1 = GeometryMath_F64.crossMatrix( v, null ); DenseMatrix64F V2 = GeometryMath_F64.crossMatrix( a, b, c, null ); assertTrue( MatrixFeatures.isIdentical( V1 ,V2 , GrlConstants.DOUBLE_TEST_TOL )); } @Test public void cross_3d_3d() { Vector3D_F64 a = new Vector3D_F64( 1, 0, 0 ); Vector3D_F64 b = new Vector3D_F64( 0, 1, 0 ); Vector3D_F64 c = new Vector3D_F64(); GeometryMath_F64.cross( a, b, c ); assertEquals( 0, c.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 0, c.y, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 1, c.z, GrlConstants.DOUBLE_TEST_TOL ); GeometryMath_F64.cross( b, a, c ); assertEquals( 0, c.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 0, c.y, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( -1, c.z, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void cross_3d_3d_double() { Vector3D_F64 a = new Vector3D_F64( 1, 2, 3 ); Vector3D_F64 b = new Vector3D_F64( 0.5, 1.5, -3 ); Vector3D_F64 expected = new Vector3D_F64(); Vector3D_F64 found = new Vector3D_F64(); GeometryMath_F64.cross( a, b, expected ); GeometryMath_F64.cross( a.x, a.y, a.z, b.x, b.y, b.z, found ); assertEquals( expected.x, found.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.y, found.y, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.z, found.z, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void cross_2d_3d() { Vector2D_F64 aa = new Vector2D_F64( 0.75, 2 ); Vector3D_F64 a = new Vector3D_F64( 0.75, 2, 1); Vector3D_F64 b = new Vector3D_F64( 3, 0.1, 4 ); Vector3D_F64 expected = new Vector3D_F64(); Vector3D_F64 found = new Vector3D_F64(); GeometryMath_F64.cross( a, b, expected ); GeometryMath_F64.cross( aa, b, found ); assertEquals( expected.x, found.x , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.y, found.y , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.z, found.z , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void cross_2d_2d() { Vector2D_F64 aa = new Vector2D_F64( 0.75, 2 ); Vector3D_F64 a = new Vector3D_F64( 0.75, 2, 1); Vector2D_F64 bb = new Vector2D_F64( 3, 0.1); Vector3D_F64 b = new Vector3D_F64( 3, 0.1, 1 ); Vector3D_F64 expected = new Vector3D_F64(); Vector3D_F64 found = new Vector3D_F64(); GeometryMath_F64.cross( a, b, expected ); GeometryMath_F64.cross( aa, bb, found ); assertEquals( expected.x, found.x , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.y, found.y , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.z, found.z , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void add() { Vector3D_F64 a = new Vector3D_F64( 1, 2, 3 ); Vector3D_F64 b = new Vector3D_F64( 3, 1, 4 ); Vector3D_F64 c = new Vector3D_F64(); GeometryMath_F64.add( a , b , c ); assertEquals( 4 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 3 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 7 , c.getZ() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void add_scale() { Vector3D_F64 a = new Vector3D_F64( 1, 2, 3 ); Vector3D_F64 b = new Vector3D_F64( 3, 1, 4 ); Vector3D_F64 c = new Vector3D_F64(); GeometryMath_F64.add( 2, a , -1 , b , c ); assertEquals( -1 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 3 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 2 , c.getZ() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void addMult() { Vector3D_F64 a = new Vector3D_F64( 1, 2, 3 ); Vector3D_F64 b = new Vector3D_F64( 2, 3, 4 ); Vector3D_F64 c = new Vector3D_F64(); DenseMatrix64F M = new DenseMatrix64F( 3,3,true,1,1,1,1,1,1,1,1,1); GeometryMath_F64.addMult( a , M , b , c ); assertEquals( 10 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 11 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 12 , c.getZ() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void sub() { Vector3D_F64 a = new Vector3D_F64( 1, 2, 3 ); Vector3D_F64 b = new Vector3D_F64( 3, 1, 4 ); Vector3D_F64 c = new Vector3D_F64(); GeometryMath_F64.sub( a , b , c ); assertEquals( -2 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 1 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( -1 , c.getZ() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void rotate_2d_theta() { Vector2D_F64 a = new Vector2D_F64( 1, 2 ); double theta = 0.6; Vector2D_F64 b = new Vector2D_F64(); GeometryMath_F64.rotate( theta,a,b); double c = Math.cos(theta); double s = Math.sin(theta); double x = c*a.x - s*a.y; double y = s*a.x + c*a.y; assertEquals(x,b.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals(y,b.y, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void rotate_2d_c_s() { Vector2D_F64 a = new Vector2D_F64( 1, 2 ); double theta = 0.6; Vector2D_F64 b = new Vector2D_F64(); double c = Math.cos(theta); double s = Math.sin(theta); GeometryMath_F64.rotate( c,s,a,b); double x = c*a.x - s*a.y; double y = s*a.x + c*a.y; assertEquals(x,b.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals(y,b.y, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void mult_3d_3d() { Vector3D_F64 a = new Vector3D_F64( -1, 2, 3 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F64 c = new Vector3D_F64(); GeometryMath_F64.mult( M , a , c ); assertEquals( 12 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 24 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 36 , c.getZ() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void mult_3d_2d() { Vector3D_F64 a = new Vector3D_F64( -1, 2, 3 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector2D_F64 c = new Vector2D_F64(); GeometryMath_F64.mult( M , a , c ); assertEquals( 12.0/36.0 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 24.0/36.0 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void mult_2d_3d() { Vector3D_F64 a3 = new Vector3D_F64( -1, 2, 1 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F64 expected = new Vector3D_F64(); GeometryMath_F64.mult( M , a3 , expected ); Vector2D_F64 a2 = new Vector2D_F64( -1, 2 ); Vector3D_F64 found = new Vector3D_F64(); GeometryMath_F64.mult( M , a2 , found ); assertEquals( expected.x , found.x , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.y , found.y , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.z , found.z , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void mult_2d_2d() { Vector3D_F64 a3 = new Vector3D_F64( -1, 2, 1 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F64 expected = new Vector3D_F64(); GeometryMath_F64.mult( M , a3 , expected ); Vector2D_F64 a2 = new Vector2D_F64( -1, 2 ); Vector2D_F64 found = new Vector2D_F64(); GeometryMath_F64.mult( M , a2 , found ); double z = expected.z; assertEquals( expected.x/z , found.x , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( expected.y/z , found.y , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void multTran_3d_3d() { Vector3D_F64 a = new Vector3D_F64( -1, 2, 3 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F64 c = new Vector3D_F64(); GeometryMath_F64.multTran( M , a , c ); assertEquals( 28 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 32 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 36 , c.getZ() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void multTran_2d_3d() { Vector2D_F64 a = new Vector2D_F64( -1, 2 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F64 c = new Vector3D_F64(); GeometryMath_F64.multTran( M , a , c ); assertEquals( 14 , c.getX() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 16 , c.getY() , GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 18 , c.getZ() , GrlConstants.DOUBLE_TEST_TOL ); } @Test public void multCrossA_2D() { Point2D_F64 a = new Point2D_F64(3,2); DenseMatrix64F b = RandomMatrices.createRandom(3,3,rand); DenseMatrix64F a_hat = GeometryMath_F64.crossMatrix(a.x,a.y,1,null); DenseMatrix64F expected = new DenseMatrix64F(3,3); CommonOps.mult(a_hat,b,expected); DenseMatrix64F found = GeometryMath_F64.multCrossA(a,b,null); assertTrue(MatrixFeatures.isIdentical(expected,found,GrlConstants.DOUBLE_TEST_TOL)); } @Test public void multCrossA_3D() { Point3D_F64 a = new Point3D_F64(1,2,3); DenseMatrix64F b = RandomMatrices.createRandom(3,3,rand); DenseMatrix64F a_hat = GeometryMath_F64.crossMatrix(a.x,a.y,a.z,null); DenseMatrix64F expected = new DenseMatrix64F(3,3); CommonOps.mult(a_hat,b,expected); DenseMatrix64F found = GeometryMath_F64.multCrossA(a,b,null); assertTrue(MatrixFeatures.isIdentical(expected,found,GrlConstants.DOUBLE_TEST_TOL)); } @Test public void innerProd_3D() { Vector3D_F64 a = new Vector3D_F64( 2, -2, 3 ); Vector3D_F64 b = new Vector3D_F64( 4, 3, 2 ); DenseMatrix64F M = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); double found = GeometryMath_F64.innerProd( a, M, b ); assertEquals( 156, found, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void innerProdTranM() { Vector3D_F64 a = new Vector3D_F64( 2, -2, 3 ); Vector3D_F64 b = new Vector3D_F64( 4, 3, 2 ); DenseMatrix64F M = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); double found = GeometryMath_F64.innerProdTranM( a, M, b ); assertEquals( 126, found, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void innerProd_2D() { Vector2D_F64 a = new Vector2D_F64( 2, -2 ); Vector2D_F64 b = new Vector2D_F64( 4, 3 ); DenseMatrix64F M = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); double found = GeometryMath_F64.innerProd( a, M, b ); assertEquals( 13, found, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void outerProd_3D() { Vector3D_F64 a = new Vector3D_F64( 2, -2 , 5); Vector3D_F64 b = new Vector3D_F64( 4, 3 , 9); DenseMatrix64F M = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); DenseMatrix64F expected = new DenseMatrix64F(3,3,true,8 , 6 ,18 , -8 ,-6,-18,20,15,45); GeometryMath_F64.outerProd( a, b , M ); assertTrue( MatrixFeatures.isIdentical(expected,M,GrlConstants.DOUBLE_TEST_TOL) ); } @Test public void addOuterProd_3D() { Vector3D_F64 a = new Vector3D_F64( 2, -2 , 5); Vector3D_F64 b = new Vector3D_F64( 4, 3 , 9); DenseMatrix64F A = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); DenseMatrix64F found = new DenseMatrix64F( 3, 3); DenseMatrix64F expected = new DenseMatrix64F(3,3,true,-7,-4,-15,12 , 11,24,-13,-7,-36); GeometryMath_F64.addOuterProd( A , -1 , a, b , found ); assertTrue( MatrixFeatures.isIdentical(expected,found,GrlConstants.DOUBLE_TEST_TOL) ); } @Test public void dot() { Vector3D_F64 a = new Vector3D_F64( 2, -2, 3 ); Vector3D_F64 b = new Vector3D_F64( 4, 3, 2 ); double found = GeometryMath_F64.dot( a, b ); assertEquals( 8, found, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void scale() { Vector3D_F64 a = new Vector3D_F64( 1, -2, 3 ); GeometryMath_F64.scale( a, 2 ); assertEquals( 2, a.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( -4, a.y, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 6, a.z, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void changeSign() { Vector3D_F64 a = new Vector3D_F64( 1, -2, 3 ); GeometryMath_F64.changeSign( a ); assertEquals( -1, a.x, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( 2, a.y, GrlConstants.DOUBLE_TEST_TOL ); assertEquals( -3, a.z, GrlConstants.DOUBLE_TEST_TOL ); } @Test public void toMatrix() { Vector3D_F64 a = new Vector3D_F64( 1, -2, 3 ); DenseMatrix64F found = GeometryMath_F64.toMatrix(a,null); assertEquals(1,found.get(0),GrlConstants.DOUBLE_TEST_TOL); assertEquals(-2,found.get(1),GrlConstants.DOUBLE_TEST_TOL); assertEquals(3,found.get(2),GrlConstants.DOUBLE_TEST_TOL); } @Test public void toTuple3D() { DenseMatrix64F a = new DenseMatrix64F(3,1,true,1,-2,3); Vector3D_F64 b = new Vector3D_F64(); GeometryMath_F64.toTuple3D(a, b); assertEquals(b.x,a.get(0),GrlConstants.DOUBLE_TEST_TOL); assertEquals(b.y,a.get(1),GrlConstants.DOUBLE_TEST_TOL); assertEquals(b.z,a.get(2),GrlConstants.DOUBLE_TEST_TOL); } }