Clover icon

Coverage Report

  1. Project Clover database Wed Sep 18 2024 02:54:09 BST
  2. Package jalview.math

File RotatableMatrix.java

 

Coverage histogram

../../img/srcFileCovDistChart8.png
20% of files have more coverage

Code metrics

16
64
11
2
259
135
22
0.34
5.82
5.5
2

Classes

Class Line # Actions
RotatableMatrix 32 64 22
0.802197880.2%
RotatableMatrix.Axis 58 0 0
-1.0 -
 

Contributing tests

This file is covered by 4 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.math;
22   
23    import jalview.datamodel.Point;
24   
25    import java.io.PrintStream;
26    import java.util.HashMap;
27    import java.util.Map;
28   
29    /**
30    * Model for a 3x3 matrix which provides methods for rotation in 3-D space
31    */
 
32    public class RotatableMatrix
33    {
34    private static final int DIMS = 3;
35   
36    /*
37    * cache the most used rotations: +/- 1, 2, 3, 4 degrees around x or y axis
38    */
39    private static Map<Axis, Map<Float, float[][]>> cachedRotations;
40   
 
41  1 toggle static
42    {
43  1 cachedRotations = new HashMap<>();
44  1 for (Axis axis : Axis.values())
45    {
46  3 HashMap<Float, float[][]> map = new HashMap<>();
47  3 cachedRotations.put(axis, map);
48  15 for (int deg = 1; deg < 5; deg++)
49    {
50  12 float[][] rotation = getRotation(deg, axis);
51  12 map.put(Float.valueOf(deg), rotation);
52  12 rotation = getRotation(-deg, axis);
53  12 map.put(Float.valueOf(-deg), rotation);
54    }
55    }
56    }
57   
 
58    public enum Axis
59    {
60    X, Y, Z
61    }
62   
63    float[][] matrix;
64   
65    /**
66    * Constructor creates a new identity matrix (all values zero except for 1 on
67    * the diagonal)
68    */
 
69  4 toggle public RotatableMatrix()
70    {
71  4 matrix = new float[DIMS][DIMS];
72  16 for (int j = 0; j < DIMS; j++)
73    {
74  12 matrix[j][j] = 1f;
75    }
76    }
77   
78    /**
79    * Sets the value at position (i, j) of the matrix
80    *
81    * @param i
82    * @param j
83    * @param value
84    */
 
85  36 toggle public void setValue(int i, int j, float value)
86    {
87  36 matrix[i][j] = value;
88    }
89   
90    /**
91    * Answers the value at position (i, j) of the matrix
92    *
93    * @param i
94    * @param j
95    * @return
96    */
 
97  9 toggle public float getValue(int i, int j)
98    {
99  9 return matrix[i][j];
100    }
101   
102    /**
103    * Prints the matrix in rows of space-delimited values
104    */
 
105  1 toggle public void print(PrintStream ps)
106    {
107  1 ps.println(matrix[0][0] + " " + matrix[0][1] + " " + matrix[0][2]);
108  1 ps.println(matrix[1][0] + " " + matrix[1][1] + " " + matrix[1][2]);
109  1 ps.println(matrix[2][0] + " " + matrix[2][1] + " " + matrix[2][2]);
110    }
111   
112    /**
113    * Rotates the matrix through the specified number of degrees around the
114    * specified axis
115    *
116    * @param degrees
117    * @param axis
118    */
 
119  0 toggle public void rotate(float degrees, Axis axis)
120    {
121  0 float[][] rot = getRotation(degrees, axis);
122   
123  0 preMultiply(rot);
124    }
125   
126    /**
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
129    *
130    * @param degrees
131    * @param axis
132    * @return
133    * @see https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations
134    */
 
135  27 toggle protected static float[][] getRotation(float degrees, Axis axis)
136    {
137  27 Float floatValue = Float.valueOf(degrees);
138  27 if (cachedRotations.get(axis).containsKey(floatValue))
139    {
140    // jalview.bin.Console.outPrintln("getRotation from cache: " + (int)
141    // degrees);
142  0 return cachedRotations.get(axis).get(floatValue);
143    }
144   
145  27 float costheta = (float) Math.cos(degrees * Math.PI / 180f);
146   
147  27 float sintheta = (float) Math.sin(degrees * Math.PI / 180f);
148   
149  27 float[][] rot = new float[DIMS][DIMS];
150   
151  27 switch (axis)
152    {
153  9 case X:
154  9 rot[0][0] = 1f;
155  9 rot[1][1] = costheta;
156  9 rot[1][2] = sintheta;
157  9 rot[2][1] = -sintheta;
158  9 rot[2][2] = costheta;
159  9 break;
160  9 case Y:
161  9 rot[0][0] = costheta;
162  9 rot[0][2] = -sintheta;
163  9 rot[1][1] = 1f;
164  9 rot[2][0] = sintheta;
165  9 rot[2][2] = costheta;
166  9 break;
167  9 case Z:
168  9 rot[0][0] = costheta;
169  9 rot[0][1] = -sintheta;
170  9 rot[1][0] = sintheta;
171  9 rot[1][1] = costheta;
172  9 rot[2][2] = 1f;
173  9 break;
174    }
175  27 return rot;
176    }
177   
178    /**
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.
183    *
184    * @param vect
185    *
186    * @return
187    */
 
188  1 toggle public float[] vectorMultiply(float[] vect)
189    {
190  1 float[] result = new float[DIMS];
191   
192  4 for (int i = 0; i < DIMS; i++)
193    {
194  3 result[i] = (matrix[i][0] * vect[0]) + (matrix[i][1] * vect[1])
195    + (matrix[i][2] * vect[2]);
196    }
197   
198  1 return result;
199    }
200   
201    /**
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.
205    *
206    * @param mat
207    */
 
208  1 toggle public void preMultiply(float[][] mat)
209    {
210  1 float[][] tmp = new float[DIMS][DIMS];
211   
212  4 for (int i = 0; i < DIMS; i++)
213    {
214  12 for (int j = 0; j < DIMS; j++)
215    {
216  9 tmp[i][j] = (mat[i][0] * matrix[0][j]) + (mat[i][1] * matrix[1][j])
217    + (mat[i][2] * matrix[2][j]);
218    }
219    }
220   
221  1 matrix = tmp;
222    }
223   
224    /**
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>.
228    *
229    * @param mat
230    */
 
231  0 toggle public void postMultiply(float[][] mat)
232    {
233  0 float[][] tmp = new float[DIMS][DIMS];
234   
235  0 for (int i = 0; i < DIMS; i++)
236    {
237  0 for (int j = 0; j < DIMS; j++)
238    {
239  0 tmp[i][j] = (matrix[i][0] * mat[0][j]) + (matrix[i][1] * mat[1][j])
240    + (matrix[i][2] * mat[2][j]);
241    }
242    }
243   
244  0 matrix = tmp;
245    }
246   
247    /**
248    * Performs a vector multiplication whose result is the Point representing the
249    * input point's value vector post-multiplied by this matrix.
250    *
251    * @param coord
252    * @return
253    */
 
254  0 toggle public Point vectorMultiply(Point coord)
255    {
256  0 float[] v = vectorMultiply(new float[] { coord.x, coord.y, coord.z });
257  0 return new Point(v[0], v[1], v[2]);
258    }
259    }