X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fmath%2FRotatableMatrixTest.java;fp=test%2Fjalview%2Fmath%2FRotatableMatrixTest.java;h=06982d52322971620dc20e242594bcc0d879a091;hb=aace9d05c0870c703bfdfb28c1608213cee019bf;hp=0000000000000000000000000000000000000000;hpb=2a3bac30ae8290e912eb7ffe7ff7ec700b6cfaac;p=jalview.git diff --git a/test/jalview/math/RotatableMatrixTest.java b/test/jalview/math/RotatableMatrixTest.java new file mode 100644 index 0000000..06982d5 --- /dev/null +++ b/test/jalview/math/RotatableMatrixTest.java @@ -0,0 +1,157 @@ +package jalview.math; + +import static org.testng.Assert.assertEquals; + +import jalview.math.RotatableMatrix.Axis; + +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class RotatableMatrixTest +{ + private RotatableMatrix rm; + + @BeforeMethod(alwaysRun = true) + public void setUp() + { + rm = new RotatableMatrix(); + + /* + * 0.5 1.0 1.5 + * 1.0 2.0 3.0 + * 1.5 3.0 4.5 + */ + for (int i = 1; i <= 3; i++) + { + for (int j = 1; j <= 3; j++) + { + rm.setValue(i - 1, j - 1, i * j / 2f); + } + } + } + + @Test(groups = "Functional") + public void testPreMultiply() + { + float[][] pre = new float[3][3]; + int i = 1; + for (int j = 0; j < 3; j++) + { + for (int k = 0; k < 3; k++) + { + pre[j][k] = i++; + } + } + + rm.preMultiply(pre); + + /* + * check rm[i, j] is now the product of the i'th row of pre + * and the j'th column of (original) rm + */ + for (int j = 0; j < 3; j++) + { + for (int k = 0; k < 3; k++) + { + float expected = 0f; + for (int l = 0; l < 3; l++) + { + float rm_l_k = (l + 1) * (k + 1) / 2f; + expected += pre[j][l] * rm_l_k; + } + assertEquals(rm.getValue(j, k), expected, + String.format("[%d, %d]", j, k)); + } + } + } + + @Test(groups = "Functional") + public void testVectorMultiply() + { + float[] result = rm.vectorMultiply(new float[] { 2f, 3f, 4.5f }); + + // vector times first column of matrix + assertEquals(result[0], 2f * 0.5f + 3f * 1f + 4.5f * 1.5f); + + // vector times second column of matrix + assertEquals(result[1], 2f * 1.0f + 3f * 2f + 4.5f * 3f); + + // vector times third column of matrix + assertEquals(result[2], 2f * 1.5f + 3f * 3f + 4.5f * 4.5f); + } + + @Test(groups = "Functional") + public void testGetRotation() + { + float theta = 60f; + double cosTheta = Math.cos((theta * Math.PI / 180f)); + double sinTheta = Math.sin((theta * Math.PI / 180f)); + + /* + * sanity check that sin(60) = sqrt(3) / 2, cos(60) = 1/2 + */ + double delta = 0.0001d; + assertEquals(cosTheta, 0.5f, delta); + assertEquals(sinTheta, Math.sqrt(3d) / 2d, delta); + + /* + * so far so good, now verify rotations + * @see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations + */ + + /* + * 60 degrees about X axis should be + * 1 0 0 + * 0 cos -sin + * 0 sin cos + * but code applies the negative of this + * nb cos(-x) = cos(x), sin(-x) = -sin(x) + */ + float[][] rot = RotatableMatrix.getRotation(theta, Axis.X); + assertEquals(rot[0][0], 1f, delta); + assertEquals(rot[0][1], 0f, delta); + assertEquals(rot[0][2], 0f, delta); + assertEquals(rot[1][0], 0f, delta); + assertEquals(rot[1][1], cosTheta, delta); + assertEquals(rot[1][2], sinTheta, delta); + assertEquals(rot[2][0], 0f, delta); + assertEquals(rot[2][1], -sinTheta, delta); + assertEquals(rot[2][2], cosTheta, delta); + + /* + * 60 degrees about Y axis should be + * cos 0 sin + * 0 1 0 + * -sin 0 cos + * but code applies the negative of this + */ + rot = RotatableMatrix.getRotation(theta, Axis.Y); + assertEquals(rot[0][0], cosTheta, delta); + assertEquals(rot[0][1], 0f, delta); + assertEquals(rot[0][2], -sinTheta, delta); + assertEquals(rot[1][0], 0f, delta); + assertEquals(rot[1][1], 1f, delta); + assertEquals(rot[1][2], 0f, delta); + assertEquals(rot[2][0], sinTheta, delta); + assertEquals(rot[2][1], 0f, delta); + assertEquals(rot[2][2], cosTheta, delta); + + /* + * 60 degrees about Z axis should be + * cos -sin 0 + * sin cos 0 + * 0 0 1 + * - and it is! + */ + rot = RotatableMatrix.getRotation(theta, Axis.Z); + assertEquals(rot[0][0], cosTheta, delta); + assertEquals(rot[0][1], -sinTheta, delta); + assertEquals(rot[0][2], 0f, delta); + assertEquals(rot[1][0], sinTheta, delta); + assertEquals(rot[1][1], cosTheta, delta); + assertEquals(rot[1][2], 0f, delta); + assertEquals(rot[2][0], 0f, delta); + assertEquals(rot[2][1], 0f, delta); + assertEquals(rot[2][2], 1f, delta); + } +}