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