Merge branch 'features/JAL-2446NCList' into features/JAL-2574findFeaturesByColumn
[jalview.git] / src / jalview / math / RotatableMatrix.java
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 /**
24  * DOCUMENT ME!
25  * 
26  * @author $author$
27  * @version $Revision$
28  */
29 public class RotatableMatrix
30 {
31   float[][] matrix;
32
33   float[] temp;
34
35   float[][] rot;
36
37   /**
38    * Creates a new RotatableMatrix object.
39    * 
40    * @param rows
41    *          DOCUMENT ME!
42    * @param cols
43    *          DOCUMENT ME!
44    */
45   public RotatableMatrix(int rows, int cols)
46   {
47     matrix = new float[rows][cols];
48
49     temp = new float[3];
50
51     rot = new float[3][3];
52   }
53
54   /**
55    * DOCUMENT ME!
56    * 
57    * @param i
58    *          DOCUMENT ME!
59    * @param j
60    *          DOCUMENT ME!
61    * @param value
62    *          DOCUMENT ME!
63    */
64   public void addElement(int i, int j, float value)
65   {
66     matrix[i][j] = value;
67   }
68
69   /**
70    * DOCUMENT ME!
71    */
72   public void print()
73   {
74     System.out.println(matrix[0][0] + " " + matrix[0][1] + " "
75             + matrix[0][2]);
76
77     System.out.println(matrix[1][0] + " " + matrix[1][1] + " "
78             + matrix[1][2]);
79
80     System.out.println(matrix[2][0] + " " + matrix[2][1] + " "
81             + matrix[2][2]);
82   }
83
84   /**
85    * DOCUMENT ME!
86    * 
87    * @param degrees
88    *          DOCUMENT ME!
89    * @param axis
90    *          DOCUMENT ME!
91    */
92   public void rotate(float degrees, char axis)
93   {
94     float costheta = (float) Math.cos((degrees * Math.PI) / (float) 180.0);
95
96     float sintheta = (float) Math.sin((degrees * Math.PI) / (float) 180.0);
97
98     if (axis == 'z')
99     {
100       rot[0][0] = (float) costheta;
101
102       rot[0][1] = (float) -sintheta;
103
104       rot[0][2] = (float) 0.0;
105
106       rot[1][0] = (float) sintheta;
107
108       rot[1][1] = (float) costheta;
109
110       rot[1][2] = (float) 0.0;
111
112       rot[2][0] = (float) 0.0;
113
114       rot[2][1] = (float) 0.0;
115
116       rot[2][2] = (float) 1.0;
117
118       preMultiply(rot);
119     }
120
121     if (axis == 'x')
122     {
123       rot[0][0] = (float) 1.0;
124
125       rot[0][1] = (float) 0.0;
126
127       rot[0][2] = (float) 0.0;
128
129       rot[1][0] = (float) 0.0;
130
131       rot[1][1] = (float) costheta;
132
133       rot[1][2] = (float) sintheta;
134
135       rot[2][0] = (float) 0.0;
136
137       rot[2][1] = (float) -sintheta;
138
139       rot[2][2] = (float) costheta;
140
141       preMultiply(rot);
142     }
143
144     if (axis == 'y')
145     {
146       rot[0][0] = (float) costheta;
147
148       rot[0][1] = (float) 0.0;
149
150       rot[0][2] = (float) -sintheta;
151
152       rot[1][0] = (float) 0.0;
153
154       rot[1][1] = (float) 1.0;
155
156       rot[1][2] = (float) 0.0;
157
158       rot[2][0] = (float) sintheta;
159
160       rot[2][1] = (float) 0.0;
161
162       rot[2][2] = (float) costheta;
163
164       preMultiply(rot);
165     }
166   }
167
168   /**
169    * DOCUMENT ME!
170    * 
171    * @param vect
172    *          DOCUMENT ME!
173    * 
174    * @return DOCUMENT ME!
175    */
176   public float[] vectorMultiply(float[] vect)
177   {
178     temp[0] = vect[0];
179
180     temp[1] = vect[1];
181
182     temp[2] = vect[2];
183
184     for (int i = 0; i < 3; i++)
185     {
186       temp[i] = (matrix[i][0] * vect[0]) + (matrix[i][1] * vect[1])
187               + (matrix[i][2] * vect[2]);
188     }
189
190     vect[0] = temp[0];
191
192     vect[1] = temp[1];
193
194     vect[2] = temp[2];
195
196     return vect;
197   }
198
199   /**
200    * DOCUMENT ME!
201    * 
202    * @param mat
203    *          DOCUMENT ME!
204    */
205   public void preMultiply(float[][] mat)
206   {
207     float[][] tmp = new float[3][3];
208
209     for (int i = 0; i < 3; i++)
210     {
211       for (int j = 0; j < 3; j++)
212       {
213         tmp[i][j] = (mat[i][0] * matrix[0][j]) + (mat[i][1] * matrix[1][j])
214                 + (mat[i][2] * matrix[2][j]);
215       }
216     }
217
218     for (int i = 0; i < 3; i++)
219     {
220       for (int j = 0; j < 3; j++)
221       {
222         matrix[i][j] = tmp[i][j];
223       }
224     }
225   }
226
227   /**
228    * DOCUMENT ME!
229    * 
230    * @param mat
231    *          DOCUMENT ME!
232    */
233   public void postMultiply(float[][] mat)
234   {
235     float[][] tmp = new float[3][3];
236
237     for (int i = 0; i < 3; i++)
238     {
239       for (int j = 0; j < 3; j++)
240       {
241         tmp[i][j] = (matrix[i][0] * mat[0][j]) + (matrix[i][1] * mat[1][j])
242                 + (matrix[i][2] * mat[2][j]);
243       }
244     }
245
246     for (int i = 0; i < 3; i++)
247     {
248       for (int j = 0; j < 3; j++)
249       {
250         matrix[i][j] = tmp[i][j];
251       }
252     }
253   }
254
255   /**
256    * DOCUMENT ME!
257    * 
258    * @param args
259    *          DOCUMENT ME!
260    */
261   public static void main(String[] args)
262   {
263     RotatableMatrix m = new RotatableMatrix(3, 3);
264
265     m.addElement(0, 0, 1);
266
267     m.addElement(0, 1, 0);
268
269     m.addElement(0, 2, 0);
270
271     m.addElement(1, 0, 0);
272
273     m.addElement(1, 1, 2);
274
275     m.addElement(1, 2, 0);
276
277     m.addElement(2, 0, 0);
278
279     m.addElement(2, 1, 0);
280
281     m.addElement(2, 2, 1);
282
283     m.print();
284
285     RotatableMatrix n = new RotatableMatrix(3, 3);
286
287     n.addElement(0, 0, 2);
288
289     n.addElement(0, 1, 1);
290
291     n.addElement(0, 2, 1);
292
293     n.addElement(1, 0, 2);
294
295     n.addElement(1, 1, 1);
296
297     n.addElement(1, 2, 1);
298
299     n.addElement(2, 0, 2);
300
301     n.addElement(2, 1, 1);
302
303     n.addElement(2, 2, 1);
304
305     n.print();
306
307     // m.postMultiply(n.matrix);
308     // m.print();
309     // m.rotate(45,'z',new RotatableMatrix(3,3));
310     float[] vect = new float[3];
311
312     vect[0] = 2;
313
314     vect[1] = 4;
315
316     vect[2] = 6;
317
318     vect = m.vectorMultiply(vect);
319
320     System.out.println(vect[0] + " " + vect[1] + " " + vect[2]);
321   }
322
323   /**
324    * DOCUMENT ME!
325    */
326   public void setIdentity()
327   {
328     matrix[0][0] = (float) 1.0;
329
330     matrix[1][1] = (float) 1.0;
331
332     matrix[2][2] = (float) 1.0;
333
334     matrix[0][1] = (float) 0.0;
335
336     matrix[0][2] = (float) 0.0;
337
338     matrix[1][0] = (float) 0.0;
339
340     matrix[1][2] = (float) 0.0;
341
342     matrix[2][0] = (float) 0.0;
343
344     matrix[2][1] = (float) 0.0;
345   }
346 }