3 import static org.testng.Assert.assertEquals;
5 import jalview.math.RotatableMatrix.Axis;
7 import java.io.ByteArrayOutputStream;
8 import java.io.PrintStream;
10 import org.testng.annotations.BeforeMethod;
11 import org.testng.annotations.Test;
13 public class RotatableMatrixTest
15 private RotatableMatrix rm;
17 @BeforeMethod(alwaysRun = true)
20 rm = new RotatableMatrix();
27 for (int i = 1; i <= 3; i++)
29 for (int j = 1; j <= 3; j++)
31 rm.setValue(i - 1, j - 1, i * j / 2f);
36 @Test(groups = "Functional")
37 public void testPrint()
39 String expected = "0.5 1.0 1.5\n1.0 2.0 3.0\n1.5 3.0 4.5\n";
40 ByteArrayOutputStream os = new ByteArrayOutputStream();
41 PrintStream ps = new PrintStream(os, true);
43 String result = new String(os.toByteArray());
44 assertEquals(result, expected);
47 @Test(groups = "Functional")
48 public void testPreMultiply()
50 float[][] pre = new float[3][3];
52 for (int j = 0; j < 3; j++)
54 for (int k = 0; k < 3; k++)
63 * check rm[i, j] is now the product of the i'th row of pre
64 * and the j'th column of (original) rm
66 for (int j = 0; j < 3; j++)
68 for (int k = 0; k < 3; k++)
71 for (int l = 0; l < 3; l++)
73 float rm_l_k = (l + 1) * (k + 1) / 2f;
74 expected += pre[j][l] * rm_l_k;
76 assertEquals(rm.getValue(j, k), expected,
77 String.format("[%d, %d]", j, k));
82 @Test(groups = "Functional")
83 public void testVectorMultiply()
85 float[] result = rm.vectorMultiply(new float[] { 2f, 3f, 4.5f });
87 // vector times first column of matrix
88 assertEquals(result[0], 2f * 0.5f + 3f * 1f + 4.5f * 1.5f);
90 // vector times second column of matrix
91 assertEquals(result[1], 2f * 1.0f + 3f * 2f + 4.5f * 3f);
93 // vector times third column of matrix
94 assertEquals(result[2], 2f * 1.5f + 3f * 3f + 4.5f * 4.5f);
97 @Test(groups = "Functional")
98 public void testGetRotation()
101 double cosTheta = Math.cos((theta * Math.PI / 180f));
102 double sinTheta = Math.sin((theta * Math.PI / 180f));
105 * sanity check that sin(60) = sqrt(3) / 2, cos(60) = 1/2
107 double delta = 0.0001d;
108 assertEquals(cosTheta, 0.5f, delta);
109 assertEquals(sinTheta, Math.sqrt(3d) / 2d, delta);
112 * so far so good, now verify rotations
113 * @see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
117 * 60 degrees about X axis should be
121 * but code applies the negative of this
122 * nb cos(-x) = cos(x), sin(-x) = -sin(x)
124 float[][] rot = RotatableMatrix.getRotation(theta, Axis.X);
125 assertEquals(rot[0][0], 1f, delta);
126 assertEquals(rot[0][1], 0f, delta);
127 assertEquals(rot[0][2], 0f, delta);
128 assertEquals(rot[1][0], 0f, delta);
129 assertEquals(rot[1][1], cosTheta, delta);
130 assertEquals(rot[1][2], sinTheta, delta);
131 assertEquals(rot[2][0], 0f, delta);
132 assertEquals(rot[2][1], -sinTheta, delta);
133 assertEquals(rot[2][2], cosTheta, delta);
136 * 60 degrees about Y axis should be
140 * but code applies the negative of this
142 rot = RotatableMatrix.getRotation(theta, Axis.Y);
143 assertEquals(rot[0][0], cosTheta, delta);
144 assertEquals(rot[0][1], 0f, delta);
145 assertEquals(rot[0][2], -sinTheta, delta);
146 assertEquals(rot[1][0], 0f, delta);
147 assertEquals(rot[1][1], 1f, delta);
148 assertEquals(rot[1][2], 0f, delta);
149 assertEquals(rot[2][0], sinTheta, delta);
150 assertEquals(rot[2][1], 0f, delta);
151 assertEquals(rot[2][2], cosTheta, delta);
154 * 60 degrees about Z axis should be
160 rot = RotatableMatrix.getRotation(theta, Axis.Z);
161 assertEquals(rot[0][0], cosTheta, delta);
162 assertEquals(rot[0][1], -sinTheta, delta);
163 assertEquals(rot[0][2], 0f, delta);
164 assertEquals(rot[1][0], sinTheta, delta);
165 assertEquals(rot[1][1], cosTheta, delta);
166 assertEquals(rot[1][2], 0f, delta);
167 assertEquals(rot[2][0], 0f, delta);
168 assertEquals(rot[2][1], 0f, delta);
169 assertEquals(rot[2][2], 1f, delta);