From 10feddcf033cb587950d5f8ec734f25611d6bd00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Thu, 17 Aug 2023 10:35:58 -0700 Subject: [PATCH] Convert MatrixMathHelperTest to Kotlin (#39046) Summary: This PR converts `MatrixMathHelperTest.java` to Kotlin as requested in [this issue](https://github.com/facebook/react-native/issues/38825). ## Changelog: [INTERNAL] [CHANGED] - Convert MatrixMathHelperTest to Kotlin Pull Request resolved: https://github.com/facebook/react-native/pull/39046 Test Plan: 1. Run `./gradlew :packages:react-native:ReactAndroid:test`. 2. All tests should pass. Reviewed By: mdvacca Differential Revision: D48430157 Pulled By: cortinico fbshipit-source-id: d371e6958a561797ffd8f9e14382a144f82f105e --- .../react/uimanager/MatrixMathHelperTest.java | 175 ---------------- .../react/uimanager/MatrixMathHelperTest.kt | 190 ++++++++++++++++++ 2 files changed, 190 insertions(+), 175 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.java create mode 100644 packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.kt diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.java b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.java deleted file mode 100644 index aab77b77bbf..00000000000 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.uimanager; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; - -/** Test for {@link MatrixMathHelper} */ -@RunWith(RobolectricTestRunner.class) -@Ignore // TODO T14964130 -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); - } - - private void verifyRotatedMatrix( - double degreesX, double degreesY, double degreesZ, double rotX, double rotY, double rotZ) { - MatrixMathHelper.MatrixDecompositionContext ctx = - new MatrixMathHelper.MatrixDecompositionContext(); - double[] matrixX = createRotateX(degreesToRadians(degreesX)); - double[] matrixY = createRotateY(degreesToRadians(degreesY)); - double[] matrixZ = createRotateZ(degreesToRadians(degreesZ)); - double[] matrix = MatrixMathHelper.createIdentityMatrix(); - MatrixMathHelper.multiplyInto(matrix, matrix, matrixX); - MatrixMathHelper.multiplyInto(matrix, matrix, matrixY); - MatrixMathHelper.multiplyInto(matrix, matrix, matrixZ); - 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}; - for (double angle : angles) { - verifyYRotatedMatrix(angle, 0d, angle, 0d); - verifyYRotatedMatrix(-angle, 0d, -angle, 0d); - } - - // all values are between -90 and 90; - // change of sign and direction in the third and fourth quadrant - verifyYRotatedMatrix(222, -180d, -42d, -180d); - - verifyYRotatedMatrix(270, -180d, -90d, -180d); - - 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); - } - - @Test - public void testDecomposingComplex4x4MatrixToProduceAccurateAngles() { - verifyRotatedMatrix(10, -80, 0, 10, -80, 0); - // x and y will flip - verifyRotatedMatrix(10, -95, 0, -170, -85, -180); - } - - 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; - } -} diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.kt new file mode 100644 index 00000000000..d60978bea2d --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/MatrixMathHelperTest.kt @@ -0,0 +1,190 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.uimanager + +import com.facebook.react.uimanager.MatrixMathHelper.MatrixDecompositionContext +import kotlin.math.cos +import kotlin.math.sin +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +/** Test for [MatrixMathHelper] */ +@RunWith(RobolectricTestRunner::class) +class MatrixMathHelperTest { + + @Test + fun testDecomposing4x4MatrixToProduceAccurateZaxisAngles() { + val ctx = MatrixDecompositionContext() + + MatrixMathHelper.decomposeMatrix( + doubleArrayOf( + 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), + ctx) + + assertThat(ctx.rotationDegrees).containsSequence(0.0, 0.0, 0.0) + + val angles = doubleArrayOf(30.0, 45.0, 60.0, 75.0, 90.0, 100.0, 115.0, 120.0, 133.0, 167.0) + for (angle in angles) { + verifyZRotatedMatrix(angle, 0.0, 0.0, angle) + verifyZRotatedMatrix(-angle, 0.0, 0.0, -angle) + } + + verifyZRotatedMatrix(180.0, 0.0, 0.0, 180.0) + + // all values are between 0 and 180; + // change of sign and direction in the third and fourth quadrant + verifyZRotatedMatrix(222.0, 0.0, 0.0, -138.0) + + verifyZRotatedMatrix(270.0, 0.0, 0.0, -90.0) + + // 360 is expressed as 0 + verifyZRotatedMatrix(360.0, 0.0, 0.0, 0.0) + + verifyZRotatedMatrix(33.33333333, 0.0, 0.0, 33.333) + + verifyZRotatedMatrix(86.75309, 0.0, 0.0, 86.753) + + verifyZRotatedMatrix(42.00000000001, 0.0, 0.0, 42.0) + + verifyZRotatedMatrix(42.99999999999, 0.0, 0.0, 43.0) + + verifyZRotatedMatrix(42.99999999999, 0.0, 0.0, 43.0) + + verifyZRotatedMatrix(42.49999999999, 0.0, 0.0, 42.5) + + verifyZRotatedMatrix(42.55555555555, 0.0, 0.0, 42.556) + } + + @Test + fun testDecomposing4x4MatrixToProduceAccurateYaxisAngles() { + val angles = doubleArrayOf(30.0, 45.0, 60.0, 75.0, 90.0) + for (angle in angles) { + verifyYRotatedMatrix(angle, 0.0, angle, 0.0) + verifyYRotatedMatrix(-angle, 0.0, -angle, 0.0) + } + + // all values are between -90 and 90; + // change of sign and direction in the third and fourth quadrant + verifyYRotatedMatrix(222.0, -180.0, -42.0, -180.0) + + verifyYRotatedMatrix(270.0, -180.0, -90.0, -180.0) + + verifyYRotatedMatrix(360.0, 0.0, 0.0, 0.0) + } + + @Test + fun testDecomposing4x4MatrixToProduceAccurateXaxisAngles() { + val angles = doubleArrayOf(30.0, 45.0, 60.0, 75.0, 90.0, 100.0, 110.0, 120.0, 133.0, 167.0) + for (angle in angles) { + verifyXRotatedMatrix(angle, angle, 0.0, 0.0) + verifyXRotatedMatrix(-angle, -angle, 0.0, 0.0) + } + + // all values are between 0 and 180; + // change of sign and direction in the third and fourth quadrant + verifyXRotatedMatrix(222.0, -138.0, 0.0, 0.0) + + verifyXRotatedMatrix(270.0, -90.0, 0.0, 0.0) + + verifyXRotatedMatrix(360.0, 0.0, 0.0, 0.0) + } + + @Test + fun testDecomposingComplex4x4MatrixToProduceAccurateAngles() { + verifyRotatedMatrix(10.0, -80.0, 0.0, 10.0, -80.0, 0.0) + // x and y will flip + verifyRotatedMatrix(10.0, -95.0, 0.0, -170.0, -85.0, -180.0) + } + + private fun verifyZRotatedMatrix(degrees: Double, rotX: Double, rotY: Double, rotZ: Double) { + val ctx = MatrixDecompositionContext() + val matrix = createRotateZ(degreesToRadians(degrees)) + + MatrixMathHelper.decomposeMatrix(matrix, ctx) + + assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ) + } + + private fun verifyYRotatedMatrix(degrees: Double, rotX: Double, rotY: Double, rotZ: Double) { + val ctx = MatrixDecompositionContext() + val matrix = createRotateY(degreesToRadians(degrees)) + + MatrixMathHelper.decomposeMatrix(matrix, ctx) + + assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ) + } + + private fun verifyXRotatedMatrix(degrees: Double, rotX: Double, rotY: Double, rotZ: Double) { + val ctx = MatrixDecompositionContext() + val matrix = createRotateX(degreesToRadians(degrees)) + + MatrixMathHelper.decomposeMatrix(matrix, ctx) + + assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ) + } + + private fun verifyRotatedMatrix( + degreesX: Double, + degreesY: Double, + degreesZ: Double, + rotX: Double, + rotY: Double, + rotZ: Double + ) { + val ctx = MatrixDecompositionContext() + val matrixX = createRotateX(degreesToRadians(degreesX)) + val matrixY = createRotateY(degreesToRadians(degreesY)) + val matrixZ = createRotateZ(degreesToRadians(degreesZ)) + val matrix = MatrixMathHelper.createIdentityMatrix() + + MatrixMathHelper.multiplyInto(matrix, matrix, matrixX) + MatrixMathHelper.multiplyInto(matrix, matrix, matrixY) + MatrixMathHelper.multiplyInto(matrix, matrix, matrixZ) + MatrixMathHelper.decomposeMatrix(matrix, ctx) + + assertThat(ctx.rotationDegrees).containsSequence(rotX, rotY, rotZ) + } + + companion object { + private fun degreesToRadians(degrees: Double): Double { + return degrees * Math.PI / 180 + } + + private fun createRotateZ(radians: Double): DoubleArray { + val mat = MatrixMathHelper.createIdentityMatrix() + mat[0] = cos(radians) + mat[1] = sin(radians) + mat[4] = -sin(radians) + mat[5] = cos(radians) + + return mat + } + + private fun createRotateY(radians: Double): DoubleArray { + val mat = MatrixMathHelper.createIdentityMatrix() + mat[0] = cos(radians) + mat[2] = -sin(radians) + mat[8] = sin(radians) + mat[10] = cos(radians) + + return mat + } + + private fun createRotateX(radians: Double): DoubleArray { + val mat = MatrixMathHelper.createIdentityMatrix() + mat[5] = cos(radians) + mat[6] = sin(radians) + mat[9] = -sin(radians) + mat[10] = cos(radians) + + return mat + } + } +}