2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import static org.testng.Assert.assertEquals;
25 import jalview.math.RotatableMatrix.Axis;
27 import java.io.ByteArrayOutputStream;
28 import java.io.PrintStream;
30 import org.testng.annotations.BeforeMethod;
31 import org.testng.annotations.Test;
33 public class RotatableMatrixTest
35 private RotatableMatrix rm;
37 @BeforeMethod(alwaysRun = true)
40 rm = new RotatableMatrix();
47 for (int i = 1; i <= 3; i++)
49 for (int j = 1; j <= 3; j++)
51 rm.setValue(i - 1, j - 1, i * j / 2f);
56 @Test(groups = "Functional")
57 public void testPrint()
59 String expected = "0.5 1.0 1.5\n1.0 2.0 3.0\n1.5 3.0 4.5\n";
60 ByteArrayOutputStream os = new ByteArrayOutputStream();
61 PrintStream ps = new PrintStream(os, true);
63 String result = new String(os.toByteArray());
64 assertEquals(result, expected);
67 @Test(groups = "Functional")
68 public void testPreMultiply()
70 float[][] pre = new float[3][3];
72 for (int j = 0; j < 3; j++)
74 for (int k = 0; k < 3; k++)
83 * check rm[i, j] is now the product of the i'th row of pre
84 * and the j'th column of (original) rm
86 for (int j = 0; j < 3; j++)
88 for (int k = 0; k < 3; k++)
91 for (int l = 0; l < 3; l++)
93 float rm_l_k = (l + 1) * (k + 1) / 2f;
94 expected += pre[j][l] * rm_l_k;
96 assertEquals(rm.getValue(j, k), expected,
97 String.format("[%d, %d]", j, k));
102 @Test(groups = "Functional")
103 public void testVectorMultiply()
105 float[] result = rm.vectorMultiply(new float[] { 2f, 3f, 4.5f });
107 // vector times first column of matrix
108 assertEquals(result[0], 2f * 0.5f + 3f * 1f + 4.5f * 1.5f);
110 // vector times second column of matrix
111 assertEquals(result[1], 2f * 1.0f + 3f * 2f + 4.5f * 3f);
113 // vector times third column of matrix
114 assertEquals(result[2], 2f * 1.5f + 3f * 3f + 4.5f * 4.5f);
117 @Test(groups = "Functional")
118 public void testGetRotation()
121 double cosTheta = Math.cos((theta * Math.PI / 180f));
122 double sinTheta = Math.sin((theta * Math.PI / 180f));
125 * sanity check that sin(60) = sqrt(3) / 2, cos(60) = 1/2
127 double delta = 0.0001d;
128 assertEquals(cosTheta, 0.5f, delta);
129 assertEquals(sinTheta, Math.sqrt(3d) / 2d, delta);
132 * so far so good, now verify rotations
133 * @see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
137 * 60 degrees about X axis should be
141 * but code applies the negative of this
142 * nb cos(-x) = cos(x), sin(-x) = -sin(x)
144 float[][] rot = RotatableMatrix.getRotation(theta, Axis.X);
145 assertEquals(rot[0][0], 1f, delta);
146 assertEquals(rot[0][1], 0f, delta);
147 assertEquals(rot[0][2], 0f, delta);
148 assertEquals(rot[1][0], 0f, delta);
149 assertEquals(rot[1][1], cosTheta, delta);
150 assertEquals(rot[1][2], sinTheta, delta);
151 assertEquals(rot[2][0], 0f, delta);
152 assertEquals(rot[2][1], -sinTheta, delta);
153 assertEquals(rot[2][2], cosTheta, delta);
156 * 60 degrees about Y axis should be
160 * but code applies the negative of this
162 rot = RotatableMatrix.getRotation(theta, Axis.Y);
163 assertEquals(rot[0][0], cosTheta, delta);
164 assertEquals(rot[0][1], 0f, delta);
165 assertEquals(rot[0][2], -sinTheta, delta);
166 assertEquals(rot[1][0], 0f, delta);
167 assertEquals(rot[1][1], 1f, delta);
168 assertEquals(rot[1][2], 0f, delta);
169 assertEquals(rot[2][0], sinTheta, delta);
170 assertEquals(rot[2][1], 0f, delta);
171 assertEquals(rot[2][2], cosTheta, delta);
174 * 60 degrees about Z axis should be
180 rot = RotatableMatrix.getRotation(theta, Axis.Z);
181 assertEquals(rot[0][0], cosTheta, delta);
182 assertEquals(rot[0][1], -sinTheta, delta);
183 assertEquals(rot[0][2], 0f, delta);
184 assertEquals(rot[1][0], sinTheta, delta);
185 assertEquals(rot[1][1], cosTheta, delta);
186 assertEquals(rot[1][2], 0f, delta);
187 assertEquals(rot[2][0], 0f, delta);
188 assertEquals(rot[2][1], 0f, delta);
189 assertEquals(rot[2][2], 1f, delta);