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 // System.out.println("getRotation from cache: " + (int) degrees);
141 return cachedRotations.get(axis).get(floatValue);
144 float costheta = (float) Math.cos(degrees * Math.PI / 180f);
146 float sintheta = (float) Math.sin(degrees * Math.PI / 180f);
148 float[][] rot = new float[DIMS][DIMS];
154 rot[1][1] = costheta;
155 rot[1][2] = sintheta;
156 rot[2][1] = -sintheta;
157 rot[2][2] = costheta;
160 rot[0][0] = costheta;
161 rot[0][2] = -sintheta;
163 rot[2][0] = sintheta;
164 rot[2][2] = costheta;
167 rot[0][0] = costheta;
168 rot[0][1] = -sintheta;
169 rot[1][0] = sintheta;
170 rot[1][1] = costheta;
178 * Answers a new array of float values which is the result of pre-multiplying
179 * this matrix by the given vector. Each value of the result is the dot
180 * product of the vector with one column of this matrix. The matrix and input
181 * vector are not modified.
187 public float[] vectorMultiply(float[] vect)
189 float[] result = new float[DIMS];
191 for (int i = 0; i < DIMS; i++)
193 result[i] = (matrix[i][0] * vect[0]) + (matrix[i][1] * vect[1])
194 + (matrix[i][2] * vect[2]);
201 * Performs pre-multiplication of this matrix by the given one. Value (i, j)
202 * of the result is the dot product of the i'th row of <code>mat</code> with
203 * the j'th column of this matrix.
207 public void preMultiply(float[][] mat)
209 float[][] tmp = new float[DIMS][DIMS];
211 for (int i = 0; i < DIMS; i++)
213 for (int j = 0; j < DIMS; j++)
215 tmp[i][j] = (mat[i][0] * matrix[0][j]) + (mat[i][1] * matrix[1][j])
216 + (mat[i][2] * matrix[2][j]);
224 * Performs post-multiplication of this matrix by the given one. Value (i, j)
225 * of the result is the dot product of the i'th row of this matrix with the
226 * j'th column of <code>mat</code>.
230 public void postMultiply(float[][] mat)
232 float[][] tmp = new float[DIMS][DIMS];
234 for (int i = 0; i < DIMS; i++)
236 for (int j = 0; j < DIMS; j++)
238 tmp[i][j] = (matrix[i][0] * mat[0][j]) + (matrix[i][1] * mat[1][j])
239 + (matrix[i][2] * mat[2][j]);
247 * Performs a vector multiplication whose result is the Point representing the
248 * input point's value vector post-multiplied by this matrix.
253 public Point vectorMultiply(Point coord)
255 float[] v = vectorMultiply(new float[] { coord.x, coord.y, coord.z });
256 return new Point(v[0], v[1], v[2]);