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
This commit is contained in:
Fábio Henriques
2023-08-17 10:35:58 -07:00
committed by Facebook GitHub Bot
parent d1e2cbb4b3
commit 10feddcf03
2 changed files with 190 additions and 175 deletions
@@ -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;
}
}
@@ -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
}
}
}