package com.facebook.react.uimanager; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import static org.fest.assertions.api.Assertions.assertThat; /** * Test for {@link MatrixMathHelper} */ @RunWith(RobolectricTestRunner.class) public class MatrixMathHelperTest { private void verifyZRotatedMatrix(double degrees, double rotX, double rotY, double rotZ) { MatrixMathHelper.MatrixDecompositionContext ctx = new MatrixMathHelper.MatrixDecompositionContext(); double[] matrix = createRotateZ(degreesToRadians(degrees)); MatrixMathHelper.decomposeMatrix(matrix, ctx); assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ); } private void verifyYRotatedMatrix(double degrees, double rotX, double rotY, double rotZ) { MatrixMathHelper.MatrixDecompositionContext ctx = new MatrixMathHelper.MatrixDecompositionContext(); double[] matrix = createRotateY(degreesToRadians(degrees)); MatrixMathHelper.decomposeMatrix(matrix, ctx); assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ); } private void verifyXRotatedMatrix(double degrees, double rotX, double rotY, double rotZ) { MatrixMathHelper.MatrixDecompositionContext ctx = new MatrixMathHelper.MatrixDecompositionContext(); double[] matrix = createRotateX(degreesToRadians(degrees)); MatrixMathHelper.decomposeMatrix(matrix, ctx); assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ); } @Test public void testDecomposing4x4MatrixToProduceAccurateZaxisAngles() { MatrixMathHelper.MatrixDecompositionContext ctx = new MatrixMathHelper.MatrixDecompositionContext(); MatrixMathHelper.decomposeMatrix( new double[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, ctx); assertThat(ctx.rotationDegrees).containsSequence(0d, 0d, 0d); double[] angles = new double[]{30, 45, 60, 75, 90, 100, 115, 120, 133, 167}; for (double angle : angles) { verifyZRotatedMatrix(angle, 0d, 0d, angle); verifyZRotatedMatrix(-angle, 0d, 0d, -angle); } verifyZRotatedMatrix(180d, 0d, 0d, 180d); // all values are between 0 and 180; // change of sign and direction in the third and fourth quadrant verifyZRotatedMatrix(222, 0d, 0d, -138d); verifyZRotatedMatrix(270, 0d, 0d, -90d); // 360 is expressed as 0 verifyZRotatedMatrix(360, 0d, 0d, 0d); verifyZRotatedMatrix(33.33333333, 0d, 0d, 33.333d); verifyZRotatedMatrix(86.75309, 0d, 0d, 86.753d); verifyZRotatedMatrix(42.00000000001, 0d, 0d, 42d); verifyZRotatedMatrix(42.99999999999, 0d, 0d, 43d); verifyZRotatedMatrix(42.99999999999, 0d, 0d, 43d); verifyZRotatedMatrix(42.49999999999, 0d, 0d, 42.5d); verifyZRotatedMatrix(42.55555555555, 0d, 0d, 42.556d); } @Test public void testDecomposing4x4MatrixToProduceAccurateYaxisAngles() { double[] angles = new double[]{30, 45, 60, 75, 90, 100, 110, 120, 133, 167}; for (double angle : angles) { verifyYRotatedMatrix(angle, 0d, angle, 0d); verifyYRotatedMatrix(-angle, 0d, -angle, 0d); } // all values are between 0 and 180; // change of sign and direction in the third and fourth quadrant verifyYRotatedMatrix(222, 0d, -138d, 0d); verifyYRotatedMatrix(270, 0d, -90d, 0d); verifyYRotatedMatrix(360, 0d, 0d, 0d); } @Test public void testDecomposing4x4MatrixToProduceAccurateXaxisAngles() { double[] angles = new double[]{30, 45, 60, 75, 90, 100, 110, 120, 133, 167}; for (double angle : angles) { verifyXRotatedMatrix(angle, angle, 0d, 0d); verifyXRotatedMatrix(-angle, -angle, 0d, 0d); } // all values are between 0 and 180; // change of sign and direction in the third and fourth quadrant verifyXRotatedMatrix(222, -138d, 0d, 0d); verifyXRotatedMatrix(270, -90d, 0d, 0d); verifyXRotatedMatrix(360, 0d, 0d, 0d); } private static double degreesToRadians(double degrees) { return degrees * Math.PI / 180; } private static double[] createRotateZ(double radians) { double[] mat = MatrixMathHelper.createIdentityMatrix(); mat[0] = Math.cos(radians); mat[1] = Math.sin(radians); mat[4] = -Math.sin(radians); mat[5] = Math.cos(radians); return mat; } private static double[] createRotateY(double radians) { double[] mat = MatrixMathHelper.createIdentityMatrix(); mat[0] = Math.cos(radians); mat[2] = -Math.sin(radians); mat[8] = Math.sin(radians); mat[10] = Math.cos(radians); return mat; } private static double[] createRotateX(double radians) { double[] mat = MatrixMathHelper.createIdentityMatrix(); mat[5] = Math.cos(radians); mat[6] = Math.sin(radians); mat[9] = -Math.sin(radians); mat[10] = Math.cos(radians); return mat; } }