Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 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
258
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    // System.out.println("getRotation from cache: " + (int) degrees);
141  0 return cachedRotations.get(axis).get(floatValue);
142    }
143   
144  27 float costheta = (float) Math.cos(degrees * Math.PI / 180f);
145   
146  27 float sintheta = (float) Math.sin(degrees * Math.PI / 180f);
147   
148  27 float[][] rot = new float[DIMS][DIMS];
149   
150  27 switch (axis)
151    {
152  9 case X:
153  9 rot[0][0] = 1f;
154  9 rot[1][1] = costheta;
155  9 rot[1][2] = sintheta;
156  9 rot[2][1] = -sintheta;
157  9 rot[2][2] = costheta;
158  9 break;
159  9 case Y:
160  9 rot[0][0] = costheta;
161  9 rot[0][2] = -sintheta;
162  9 rot[1][1] = 1f;
163  9 rot[2][0] = sintheta;
164  9 rot[2][2] = costheta;
165  9 break;
166  9 case Z:
167  9 rot[0][0] = costheta;
168  9 rot[0][1] = -sintheta;
169  9 rot[1][0] = sintheta;
170  9 rot[1][1] = costheta;
171  9 rot[2][2] = 1f;
172  9 break;
173    }
174  27 return rot;
175    }
176   
177    /**
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.
182    *
183    * @param vect
184    *
185    * @return
186    */
 
187  1 toggle public float[] vectorMultiply(float[] vect)
188    {
189  1 float[] result = new float[DIMS];
190   
191  4 for (int i = 0; i < DIMS; i++)
192    {
193  3 result[i] = (matrix[i][0] * vect[0]) + (matrix[i][1] * vect[1])
194    + (matrix[i][2] * vect[2]);
195    }
196   
197  1 return result;
198    }
199   
200    /**
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.
204    *
205    * @param mat
206    */
 
207  1 toggle public void preMultiply(float[][] mat)
208    {
209  1 float[][] tmp = new float[DIMS][DIMS];
210   
211  4 for (int i = 0; i < DIMS; i++)
212    {
213  12 for (int j = 0; j < DIMS; j++)
214    {
215  9 tmp[i][j] = (mat[i][0] * matrix[0][j]) + (mat[i][1] * matrix[1][j])
216    + (mat[i][2] * matrix[2][j]);
217    }
218    }
219   
220  1 matrix = tmp;
221    }
222   
223    /**
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>.
227    *
228    * @param mat
229    */
 
230  0 toggle public void postMultiply(float[][] mat)
231    {
232  0 float[][] tmp = new float[DIMS][DIMS];
233   
234  0 for (int i = 0; i < DIMS; i++)
235    {
236  0 for (int j = 0; j < DIMS; j++)
237    {
238  0 tmp[i][j] = (matrix[i][0] * mat[0][j]) + (matrix[i][1] * mat[1][j])
239    + (matrix[i][2] * mat[2][j]);
240    }
241    }
242   
243  0 matrix = tmp;
244    }
245   
246    /**
247    * Performs a vector multiplication whose result is the Point representing the
248    * input point's value vector post-multiplied by this matrix.
249    *
250    * @param coord
251    * @return
252    */
 
253  0 toggle public Point vectorMultiply(Point coord)
254    {
255  0 float[] v = vectorMultiply(new float[] { coord.x, coord.y, coord.z });
256  0 return new Point(v[0], v[1], v[2]);
257    }
258    }