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 jalview.datamodel.Point;
25 import java.io.PrintStream;
26 import java.util.HashMap;
30 * Model for a 3x3 matrix which provides methods for rotation in 3-D space
32 public class RotatableMatrix
34 private static final int DIMS = 3;
37 * cache the most used rotations: +/- 1, 2, 3, 4 degrees around x or y axis
39 private static Map<Axis, Map<Float, float[][]>> cachedRotations;
43 cachedRotations = new HashMap<>();
44 for (Axis axis : Axis.values())
46 HashMap<Float, float[][]> map = new HashMap<>();
47 cachedRotations.put(axis, map);
48 for (int deg = 1; deg < 5; deg++)
50 float[][] rotation = getRotation(deg, axis);
51 map.put(Float.valueOf(deg), rotation);
52 rotation = getRotation(-deg, axis);
53 map.put(Float.valueOf(-deg), rotation);
66 * Constructor creates a new identity matrix (all values zero except for 1 on
69 public RotatableMatrix()
71 matrix = new float[DIMS][DIMS];
72 for (int j = 0; j < DIMS; j++)
79 * Sets the value at position (i, j) of the matrix
85 public void setValue(int i, int j, float value)
91 * Answers the value at position (i, j) of the matrix
97 public float getValue(int i, int j)
103 * Prints the matrix in rows of space-delimited values
105 public void print(PrintStream ps)
107 ps.println(matrix[0][0] + " " + matrix[0][1] + " " + matrix[0][2]);
108 ps.println(matrix[1][0] + " " + matrix[1][1] + " " + matrix[1][2]);
109 ps.println(matrix[2][0] + " " + matrix[2][1] + " " + matrix[2][2]);
113 * Rotates the matrix through the specified number of degrees around the
119 public void rotate(float degrees, Axis axis)
121 float[][] rot = getRotation(degrees, axis);
127 * Answers a matrix which, when it pre-multiplies another matrix, applies a
128 * rotation of the specified number of degrees around the specified axis
133 * @see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
135 protected static float[][] getRotation(float degrees, Axis axis)
137 Float floatValue = Float.valueOf(degrees);
138 if (cachedRotations.get(axis).containsKey(floatValue))
140 // jalview.bin.Console.outPrintln("getRotation from cache: " + (int)
142 return cachedRotations.get(axis).get(floatValue);
145 float costheta = (float) Math.cos(degrees * Math.PI / 180f);
147 float sintheta = (float) Math.sin(degrees * Math.PI / 180f);
149 float[][] rot = new float[DIMS][DIMS];
155 rot[1][1] = costheta;
156 rot[1][2] = sintheta;
157 rot[2][1] = -sintheta;
158 rot[2][2] = costheta;
161 rot[0][0] = costheta;
162 rot[0][2] = -sintheta;
164 rot[2][0] = sintheta;
165 rot[2][2] = costheta;
168 rot[0][0] = costheta;
169 rot[0][1] = -sintheta;
170 rot[1][0] = sintheta;
171 rot[1][1] = costheta;
179 * Answers a new array of float values which is the result of pre-multiplying
180 * this matrix by the given vector. Each value of the result is the dot
181 * product of the vector with one column of this matrix. The matrix and input
182 * vector are not modified.
188 public float[] vectorMultiply(float[] vect)
190 float[] result = new float[DIMS];
192 for (int i = 0; i < DIMS; i++)
194 result[i] = (matrix[i][0] * vect[0]) + (matrix[i][1] * vect[1])
195 + (matrix[i][2] * vect[2]);
202 * Performs pre-multiplication of this matrix by the given one. Value (i, j)
203 * of the result is the dot product of the i'th row of <code>mat</code> with
204 * the j'th column of this matrix.
208 public void preMultiply(float[][] mat)
210 float[][] tmp = new float[DIMS][DIMS];
212 for (int i = 0; i < DIMS; i++)
214 for (int j = 0; j < DIMS; j++)
216 tmp[i][j] = (mat[i][0] * matrix[0][j]) + (mat[i][1] * matrix[1][j])
217 + (mat[i][2] * matrix[2][j]);
225 * Performs post-multiplication of this matrix by the given one. Value (i, j)
226 * of the result is the dot product of the i'th row of this matrix with the
227 * j'th column of <code>mat</code>.
231 public void postMultiply(float[][] mat)
233 float[][] tmp = new float[DIMS][DIMS];
235 for (int i = 0; i < DIMS; i++)
237 for (int j = 0; j < DIMS; j++)
239 tmp[i][j] = (matrix[i][0] * mat[0][j]) + (matrix[i][1] * mat[1][j])
240 + (matrix[i][2] * mat[2][j]);
248 * Performs a vector multiplication whose result is the Point representing the
249 * input point's value vector post-multiplied by this matrix.
254 public Point vectorMultiply(Point coord)
256 float[] v = vectorMultiply(new float[] { coord.x, coord.y, coord.z });
257 return new Point(v[0], v[1], v[2]);