1 /* xform.c
2 
3    MolScript v2.1.2
4 
5    Coordinate transformation.
6 
7    Copyright (C) 1997-1998 Per Kraulis
8      6-Apr-1997  split out of coord.c
9     23-Jun-1997  added axis rotation
10 */
11 
12 #include <assert.h>
13 
14 #include "clib/angle.h"
15 #include "clib/matrix3.h"
16 #include "clib/quaternion.h"
17 
18 #include "xform.h"
19 #include "global.h"
20 #include "select.h"
21 
22 
23 /*============================================================*/
24 double xform[4][4];
25 
26 static double tmp_xform[4][4];
27 static double stored_xform[4][4];
28 
29 
30 /*------------------------------------------------------------*/
31 void
xform_init(void)32 xform_init (void)
33 {
34   matrix3_initialize (xform);
35 }
36 
37 
38 /*------------------------------------------------------------*/
39 void
xform_init_stored(void)40 xform_init_stored (void)
41 {
42   matrix3_initialize (stored_xform);
43 }
44 
45 
46 /*------------------------------------------------------------*/
47 void
xform_store(void)48 xform_store (void)
49 {
50   matrix3_copy (stored_xform, xform);
51 }
52 
53 
54 /*------------------------------------------------------------*/
55 void
xform_centre(void)56 xform_centre (void)
57 {
58   assert (dstack_size == 3);
59 
60   matrix3_translation (tmp_xform, - dstack[0], - dstack[1], - dstack[2]);
61   matrix3_concatenate (xform, tmp_xform);
62 
63   clear_dstack();
64 }
65 
66 
67 /*------------------------------------------------------------*/
68 void
xform_translation(void)69 xform_translation (void)
70 {
71   assert (dstack_size == 3);
72 
73   matrix3_translation (tmp_xform, dstack[0], dstack[1], dstack[2]);
74   matrix3_concatenate (xform, tmp_xform);
75 
76   clear_dstack();
77 }
78 
79 
80 /*------------------------------------------------------------*/
81 void
xform_rotation_x(void)82 xform_rotation_x (void)
83 {
84   assert (dstack_size == 1);
85 
86   matrix3_x_rotation (tmp_xform, to_radians (dstack[0]));
87   matrix3_concatenate (xform, tmp_xform);
88 
89   clear_dstack();
90 }
91 
92 
93 /*------------------------------------------------------------*/
94 void
xform_rotation_y(void)95 xform_rotation_y (void)
96 {
97   assert (dstack_size == 1);
98 
99   matrix3_y_rotation (tmp_xform, to_radians (dstack[0]));
100   matrix3_concatenate (xform, tmp_xform);
101 
102   clear_dstack();
103 }
104 
105 
106 /*------------------------------------------------------------*/
107 void
xform_rotation_z(void)108 xform_rotation_z (void)
109 {
110   assert (dstack_size == 1);
111 
112   matrix3_z_rotation (tmp_xform, to_radians (dstack[0]));
113   matrix3_concatenate (xform, tmp_xform);
114 
115   clear_dstack();
116 }
117 
118 
119 /*------------------------------------------------------------*/
120 void
xform_rotation_axis(void)121 xform_rotation_axis (void)
122 {
123   vector3 v;
124   quaternion q;
125 
126   assert (dstack_size == 4);
127 
128   v3_initialize (&v, dstack[0], dstack[1], dstack[2]);
129   if (v3_length (&v) <= 1.0e-10) {
130     yyerror ("invalid rotation axis: zero length");
131     return;
132   }
133   quat_initialize_v3 (&q, &v, to_radians (dstack[3]));
134   quat_to_matrix3 (tmp_xform, &q);
135   matrix3_concatenate (xform, tmp_xform);
136 
137   clear_dstack();
138 }
139 
140 
141 /*------------------------------------------------------------*/
142 void
xform_rotation_matrix(void)143 xform_rotation_matrix (void)
144 {
145   assert (dstack_size == 9);
146 
147   matrix3_initialize (tmp_xform);
148   tmp_xform[0][0] = dstack[0];
149   tmp_xform[1][0] = dstack[1];
150   tmp_xform[2][0] = dstack[2];
151   tmp_xform[0][1] = dstack[3];
152   tmp_xform[1][1] = dstack[4];
153   tmp_xform[2][1] = dstack[5];
154   tmp_xform[0][2] = dstack[6];
155   tmp_xform[1][2] = dstack[7];
156   tmp_xform[2][2] = dstack[8];
157   matrix3_concatenate (xform, tmp_xform);
158 
159   clear_dstack();
160 }
161 
162 
163 /*------------------------------------------------------------*/
164 void
xform_recall_matrix(void)165 xform_recall_matrix (void)
166 {
167   matrix3_concatenate (xform, stored_xform);
168 }
169 
170 
171 /*------------------------------------------------------------*/
172 void
xform_atoms(void)173 xform_atoms (void)
174 {
175   mol3d *mol;
176   res3d *res;
177   at3d *at;
178   int *flags;
179   int count = 0;
180   named_data *nd;
181 
182   assert (count_atom_selections() == 1);
183 
184   flags = current_atom_sel->flags;
185   for (mol = first_molecule; mol; mol = mol->next) {
186     for (res = mol->first; res; res = res->next) {
187       for (at = res->first; at; at = at->next) {
188 	if (*flags++) {
189 	  matrix3_transform (&(at->xyz), xform);
190 	  count++;
191 	}
192       }
193     }
194   }
195 
196   pop_atom_selection();
197 
198   if (message_mode) {
199     int i, j;
200     fprintf (stderr, "%i atoms selected for transform\n", count);
201     fprintf (stderr, "rotation matrix applied:\n");
202     for (i = 0; i < 3; i++) {
203       for (j = 0; j < 3; j++)
204 	fprintf (stderr, "%.8f ", xform[j][i]);
205       fprintf (stderr, "\n");
206     }
207     fprintf (stderr, "translation vector applied:\n");
208     for (i = 0; i < 3; i++)
209       fprintf (stderr, "%.4f ", xform[3][i]);
210     fprintf (stderr, "\n");
211   }
212 
213   assert (count_atom_selections() == 0);
214 }
215