3 import static org.testng.Assert.assertEquals;
5 import jalview.math.RotatableMatrix.Axis;
7 import org.testng.annotations.BeforeMethod;
8 import org.testng.annotations.Test;
10 public class RotatableMatrixTest
12 private RotatableMatrix rm;
14 @BeforeMethod(alwaysRun = true)
17 rm = new RotatableMatrix();
24 for (int i = 1; i <= 3; i++)
26 for (int j = 1; j <= 3; j++)
28 rm.setValue(i - 1, j - 1, i * j / 2f);
33 @Test(groups = "Functional")
34 public void testPreMultiply()
36 float[][] pre = new float[3][3];
38 for (int j = 0; j < 3; j++)
40 for (int k = 0; k < 3; k++)
49 * check rm[i, j] is now the product of the i'th row of pre
50 * and the j'th column of (original) rm
52 for (int j = 0; j < 3; j++)
54 for (int k = 0; k < 3; k++)
57 for (int l = 0; l < 3; l++)
59 float rm_l_k = (l + 1) * (k + 1) / 2f;
60 expected += pre[j][l] * rm_l_k;
62 assertEquals(rm.getValue(j, k), expected,
63 String.format("[%d, %d]", j, k));
68 @Test(groups = "Functional")
69 public void testVectorMultiply()
71 float[] result = rm.vectorMultiply(new float[] { 2f, 3f, 4.5f });
73 // vector times first column of matrix
74 assertEquals(result[0], 2f * 0.5f + 3f * 1f + 4.5f * 1.5f);
76 // vector times second column of matrix
77 assertEquals(result[1], 2f * 1.0f + 3f * 2f + 4.5f * 3f);
79 // vector times third column of matrix
80 assertEquals(result[2], 2f * 1.5f + 3f * 3f + 4.5f * 4.5f);
83 @Test(groups = "Functional")
84 public void testGetRotation()
87 double cosTheta = Math.cos((theta * Math.PI / 180f));
88 double sinTheta = Math.sin((theta * Math.PI / 180f));
91 * sanity check that sin(60) = sqrt(3) / 2, cos(60) = 1/2
93 double delta = 0.0001d;
94 assertEquals(cosTheta, 0.5f, delta);
95 assertEquals(sinTheta, Math.sqrt(3d) / 2d, delta);
98 * so far so good, now verify rotations
99 * @see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
103 * 60 degrees about X axis should be
107 * but code applies the negative of this
108 * nb cos(-x) = cos(x), sin(-x) = -sin(x)
110 float[][] rot = RotatableMatrix.getRotation(theta, Axis.X);
111 assertEquals(rot[0][0], 1f, delta);
112 assertEquals(rot[0][1], 0f, delta);
113 assertEquals(rot[0][2], 0f, delta);
114 assertEquals(rot[1][0], 0f, delta);
115 assertEquals(rot[1][1], cosTheta, delta);
116 assertEquals(rot[1][2], sinTheta, delta);
117 assertEquals(rot[2][0], 0f, delta);
118 assertEquals(rot[2][1], -sinTheta, delta);
119 assertEquals(rot[2][2], cosTheta, delta);
122 * 60 degrees about Y axis should be
126 * but code applies the negative of this
128 rot = RotatableMatrix.getRotation(theta, Axis.Y);
129 assertEquals(rot[0][0], cosTheta, delta);
130 assertEquals(rot[0][1], 0f, delta);
131 assertEquals(rot[0][2], -sinTheta, delta);
132 assertEquals(rot[1][0], 0f, delta);
133 assertEquals(rot[1][1], 1f, delta);
134 assertEquals(rot[1][2], 0f, delta);
135 assertEquals(rot[2][0], sinTheta, delta);
136 assertEquals(rot[2][1], 0f, delta);
137 assertEquals(rot[2][2], cosTheta, delta);
140 * 60 degrees about Z axis should be
146 rot = RotatableMatrix.getRotation(theta, Axis.Z);
147 assertEquals(rot[0][0], cosTheta, delta);
148 assertEquals(rot[0][1], -sinTheta, delta);
149 assertEquals(rot[0][2], 0f, delta);
150 assertEquals(rot[1][0], sinTheta, delta);
151 assertEquals(rot[1][1], cosTheta, delta);
152 assertEquals(rot[1][2], 0f, delta);
153 assertEquals(rot[2][0], 0f, delta);
154 assertEquals(rot[2][1], 0f, delta);
155 assertEquals(rot[2][2], 1f, delta);