/* * 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_F32; import georegression.struct.point.Point3D_F32; import georegression.struct.point.Vector2D_F32; import georegression.struct.point.Vector3D_F32; 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_F32 { Random rand = new Random( 0x33 ); /** * Sees if crossMatrix produces a valid output */ @Test public void crossMatrix_validOut() { float a = 1.1f, b = -0.5f, c = 2.2f; Vector3D_F32 v = new Vector3D_F32( a, b, c ); Vector3D_F32 x = new Vector3D_F32( 7.6f, 2.9f, 0.5f ); Vector3D_F32 found0 = new Vector3D_F32(); Vector3D_F32 found1 = new Vector3D_F32(); GeometryMath_F32.cross( v, x, found0 ); DenseMatrix64F V = GeometryMath_F32.crossMatrix( a, b, c, null ); GeometryMath_F32.mult( V, x, found1 ); assertEquals( found0.x, found1.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals( found0.y, found1.y, GrlConstants.FLOAT_TEST_TOL ); assertEquals( found0.z, found1.z, GrlConstants.FLOAT_TEST_TOL ); } /** * Sees if both crossMatrix functions produce the same output */ @Test public void crossMatrix_sameOut() { float a = 1.1f, b = -0.5f, c = 2.2f; Vector3D_F32 v = new Vector3D_F32( a, b, c ); DenseMatrix64F V1 = GeometryMath_F32.crossMatrix( v, null ); DenseMatrix64F V2 = GeometryMath_F32.crossMatrix( a, b, c, null ); assertTrue( MatrixFeatures.isIdentical( V1 ,V2 , GrlConstants.FLOAT_TEST_TOL )); } @Test public void cross_3d_3d() { Vector3D_F32 a = new Vector3D_F32( 1, 0, 0 ); Vector3D_F32 b = new Vector3D_F32( 0, 1, 0 ); Vector3D_F32 c = new Vector3D_F32(); GeometryMath_F32.cross( a, b, c ); assertEquals( 0, c.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals( 0, c.y, GrlConstants.FLOAT_TEST_TOL ); assertEquals( 1, c.z, GrlConstants.FLOAT_TEST_TOL ); GeometryMath_F32.cross( b, a, c ); assertEquals( 0, c.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals( 0, c.y, GrlConstants.FLOAT_TEST_TOL ); assertEquals( -1, c.z, GrlConstants.FLOAT_TEST_TOL ); } @Test public void cross_3d_3d_float() { Vector3D_F32 a = new Vector3D_F32( 1, 2, 3 ); Vector3D_F32 b = new Vector3D_F32( 0.5f, 1.5f, -3 ); Vector3D_F32 expected = new Vector3D_F32(); Vector3D_F32 found = new Vector3D_F32(); GeometryMath_F32.cross( a, b, expected ); GeometryMath_F32.cross( a.x, a.y, a.z, b.x, b.y, b.z, found ); assertEquals( expected.x, found.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.y, found.y, GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.z, found.z, GrlConstants.FLOAT_TEST_TOL ); } @Test public void cross_2d_3d() { Vector2D_F32 aa = new Vector2D_F32( 0.75f, 2 ); Vector3D_F32 a = new Vector3D_F32( 0.75f, 2, 1); Vector3D_F32 b = new Vector3D_F32( 3, 0.1f, 4 ); Vector3D_F32 expected = new Vector3D_F32(); Vector3D_F32 found = new Vector3D_F32(); GeometryMath_F32.cross( a, b, expected ); GeometryMath_F32.cross( aa, b, found ); assertEquals( expected.x, found.x , GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.y, found.y , GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.z, found.z , GrlConstants.FLOAT_TEST_TOL ); } @Test public void cross_2d_2d() { Vector2D_F32 aa = new Vector2D_F32( 0.75f, 2 ); Vector3D_F32 a = new Vector3D_F32( 0.75f, 2, 1); Vector2D_F32 bb = new Vector2D_F32( 3, 0.1f); Vector3D_F32 b = new Vector3D_F32( 3, 0.1f, 1 ); Vector3D_F32 expected = new Vector3D_F32(); Vector3D_F32 found = new Vector3D_F32(); GeometryMath_F32.cross( a, b, expected ); GeometryMath_F32.cross( aa, bb, found ); assertEquals( expected.x, found.x , GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.y, found.y , GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.z, found.z , GrlConstants.FLOAT_TEST_TOL ); } @Test public void add() { Vector3D_F32 a = new Vector3D_F32( 1, 2, 3 ); Vector3D_F32 b = new Vector3D_F32( 3, 1, 4 ); Vector3D_F32 c = new Vector3D_F32(); GeometryMath_F32.add( a , b , c ); assertEquals( 4 , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 3 , c.getY() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 7 , c.getZ() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void add_scale() { Vector3D_F32 a = new Vector3D_F32( 1, 2, 3 ); Vector3D_F32 b = new Vector3D_F32( 3, 1, 4 ); Vector3D_F32 c = new Vector3D_F32(); GeometryMath_F32.add( 2, a , -1 , b , c ); assertEquals( -1 , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 3 , c.getY() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 2 , c.getZ() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void addMult() { Vector3D_F32 a = new Vector3D_F32( 1, 2, 3 ); Vector3D_F32 b = new Vector3D_F32( 2, 3, 4 ); Vector3D_F32 c = new Vector3D_F32(); DenseMatrix64F M = new DenseMatrix64F( 3,3,true,1,1,1,1,1,1,1,1,1); GeometryMath_F32.addMult( a , M , b , c ); assertEquals( 10 , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 11 , c.getY() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 12 , c.getZ() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void sub() { Vector3D_F32 a = new Vector3D_F32( 1, 2, 3 ); Vector3D_F32 b = new Vector3D_F32( 3, 1, 4 ); Vector3D_F32 c = new Vector3D_F32(); GeometryMath_F32.sub( a , b , c ); assertEquals( -2 , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 1 , c.getY() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( -1 , c.getZ() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void rotate_2d_theta() { Vector2D_F32 a = new Vector2D_F32( 1, 2 ); float theta = 0.6f; Vector2D_F32 b = new Vector2D_F32(); GeometryMath_F32.rotate( theta,a,b); float c = (float)Math.cos(theta); float s = (float)Math.sin(theta); float x = c*a.x - s*a.y; float y = s*a.x + c*a.y; assertEquals(x,b.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals(y,b.y, GrlConstants.FLOAT_TEST_TOL ); } @Test public void rotate_2d_c_s() { Vector2D_F32 a = new Vector2D_F32( 1, 2 ); float theta = 0.6f; Vector2D_F32 b = new Vector2D_F32(); float c = (float)Math.cos(theta); float s = (float)Math.sin(theta); GeometryMath_F32.rotate( c,s,a,b); float x = c*a.x - s*a.y; float y = s*a.x + c*a.y; assertEquals(x,b.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals(y,b.y, GrlConstants.FLOAT_TEST_TOL ); } @Test public void mult_3d_3d() { Vector3D_F32 a = new Vector3D_F32( -1, 2, 3 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F32 c = new Vector3D_F32(); GeometryMath_F32.mult( M , a , c ); assertEquals( 12 , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 24 , c.getY() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 36 , c.getZ() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void mult_3d_2d() { Vector3D_F32 a = new Vector3D_F32( -1, 2, 3 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector2D_F32 c = new Vector2D_F32(); GeometryMath_F32.mult( M , a , c ); assertEquals( 12.0f/36.0f , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 24.0f/36.0f , c.getY() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void mult_2d_3d() { Vector3D_F32 a3 = new Vector3D_F32( -1, 2, 1 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F32 expected = new Vector3D_F32(); GeometryMath_F32.mult( M , a3 , expected ); Vector2D_F32 a2 = new Vector2D_F32( -1, 2 ); Vector3D_F32 found = new Vector3D_F32(); GeometryMath_F32.mult( M , a2 , found ); assertEquals( expected.x , found.x , GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.y , found.y , GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.z , found.z , GrlConstants.FLOAT_TEST_TOL ); } @Test public void mult_2d_2d() { Vector3D_F32 a3 = new Vector3D_F32( -1, 2, 1 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F32 expected = new Vector3D_F32(); GeometryMath_F32.mult( M , a3 , expected ); Vector2D_F32 a2 = new Vector2D_F32( -1, 2 ); Vector2D_F32 found = new Vector2D_F32(); GeometryMath_F32.mult( M , a2 , found ); float z = expected.z; assertEquals( expected.x/z , found.x , GrlConstants.FLOAT_TEST_TOL ); assertEquals( expected.y/z , found.y , GrlConstants.FLOAT_TEST_TOL ); } @Test public void multTran_3d_3d() { Vector3D_F32 a = new Vector3D_F32( -1, 2, 3 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F32 c = new Vector3D_F32(); GeometryMath_F32.multTran( M , a , c ); assertEquals( 28 , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 32 , c.getY() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 36 , c.getZ() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void multTran_2d_3d() { Vector2D_F32 a = new Vector2D_F32( -1, 2 ); DenseMatrix64F M = new DenseMatrix64F(3,3,true,1,2,3,4,5,6,7,8,9); Vector3D_F32 c = new Vector3D_F32(); GeometryMath_F32.multTran( M , a , c ); assertEquals( 14 , c.getX() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 16 , c.getY() , GrlConstants.FLOAT_TEST_TOL ); assertEquals( 18 , c.getZ() , GrlConstants.FLOAT_TEST_TOL ); } @Test public void multCrossA_2D() { Point2D_F32 a = new Point2D_F32(3,2); DenseMatrix64F b = RandomMatrices.createRandom(3,3,rand); DenseMatrix64F a_hat = GeometryMath_F32.crossMatrix(a.x,a.y,1,null); DenseMatrix64F expected = new DenseMatrix64F(3,3); CommonOps.mult(a_hat,b,expected); DenseMatrix64F found = GeometryMath_F32.multCrossA(a,b,null); assertTrue(MatrixFeatures.isIdentical(expected,found,GrlConstants.FLOAT_TEST_TOL)); } @Test public void multCrossA_3D() { Point3D_F32 a = new Point3D_F32(1,2,3); DenseMatrix64F b = RandomMatrices.createRandom(3,3,rand); DenseMatrix64F a_hat = GeometryMath_F32.crossMatrix(a.x,a.y,a.z,null); DenseMatrix64F expected = new DenseMatrix64F(3,3); CommonOps.mult(a_hat,b,expected); DenseMatrix64F found = GeometryMath_F32.multCrossA(a,b,null); assertTrue(MatrixFeatures.isIdentical(expected,found,GrlConstants.FLOAT_TEST_TOL)); } @Test public void innerProd_3D() { Vector3D_F32 a = new Vector3D_F32( 2, -2, 3 ); Vector3D_F32 b = new Vector3D_F32( 4, 3, 2 ); DenseMatrix64F M = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); float found = GeometryMath_F32.innerProd( a, M, b ); assertEquals( 156, found, GrlConstants.FLOAT_TEST_TOL ); } @Test public void innerProdTranM() { Vector3D_F32 a = new Vector3D_F32( 2, -2, 3 ); Vector3D_F32 b = new Vector3D_F32( 4, 3, 2 ); DenseMatrix64F M = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); float found = GeometryMath_F32.innerProdTranM( a, M, b ); assertEquals( 126, found, GrlConstants.FLOAT_TEST_TOL ); } @Test public void innerProd_2D() { Vector2D_F32 a = new Vector2D_F32( 2, -2 ); Vector2D_F32 b = new Vector2D_F32( 4, 3 ); DenseMatrix64F M = new DenseMatrix64F( 3, 3, true, 1, 2, 3, 4, 5, 6, 7, 8, 9 ); float found = GeometryMath_F32.innerProd( a, M, b ); assertEquals( 13, found, GrlConstants.FLOAT_TEST_TOL ); } @Test public void outerProd_3D() { Vector3D_F32 a = new Vector3D_F32( 2, -2 , 5); Vector3D_F32 b = new Vector3D_F32( 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_F32.outerProd( a, b , M ); assertTrue( MatrixFeatures.isIdentical(expected,M,GrlConstants.FLOAT_TEST_TOL) ); } @Test public void addOuterProd_3D() { Vector3D_F32 a = new Vector3D_F32( 2, -2 , 5); Vector3D_F32 b = new Vector3D_F32( 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_F32.addOuterProd( A , -1 , a, b , found ); assertTrue( MatrixFeatures.isIdentical(expected,found,GrlConstants.FLOAT_TEST_TOL) ); } @Test public void dot() { Vector3D_F32 a = new Vector3D_F32( 2, -2, 3 ); Vector3D_F32 b = new Vector3D_F32( 4, 3, 2 ); float found = GeometryMath_F32.dot( a, b ); assertEquals( 8, found, GrlConstants.FLOAT_TEST_TOL ); } @Test public void scale() { Vector3D_F32 a = new Vector3D_F32( 1, -2, 3 ); GeometryMath_F32.scale( a, 2 ); assertEquals( 2, a.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals( -4, a.y, GrlConstants.FLOAT_TEST_TOL ); assertEquals( 6, a.z, GrlConstants.FLOAT_TEST_TOL ); } @Test public void changeSign() { Vector3D_F32 a = new Vector3D_F32( 1, -2, 3 ); GeometryMath_F32.changeSign( a ); assertEquals( -1, a.x, GrlConstants.FLOAT_TEST_TOL ); assertEquals( 2, a.y, GrlConstants.FLOAT_TEST_TOL ); assertEquals( -3, a.z, GrlConstants.FLOAT_TEST_TOL ); } @Test public void toMatrix() { Vector3D_F32 a = new Vector3D_F32( 1, -2, 3 ); DenseMatrix64F found = GeometryMath_F32.toMatrix(a,null); assertEquals(1,found.get(0),GrlConstants.FLOAT_TEST_TOL); assertEquals(-2,found.get(1),GrlConstants.FLOAT_TEST_TOL); assertEquals(3,found.get(2),GrlConstants.FLOAT_TEST_TOL); } @Test public void toTuple3D() { DenseMatrix64F a = new DenseMatrix64F(3,1,true,1,-2,3); Vector3D_F32 b = new Vector3D_F32(); GeometryMath_F32.toTuple3D(a, b); assertEquals(b.x,a.get(0),GrlConstants.FLOAT_TEST_TOL); assertEquals(b.y,a.get(1),GrlConstants.FLOAT_TEST_TOL); assertEquals(b.z,a.get(2),GrlConstants.FLOAT_TEST_TOL); } }