1 /* Copyright (C) 2000-2002 Damir Zucic */
2
3 /*=============================================================================
4
5 rotate.c
6
7 Purpose:
8 Rotate all caught macromolecular complexes or edit default complex.
9
10 Input:
11 (1) Pointer to MolComplexS structure, with macromolecular complexes.
12 (2) Number of macromolecular complexes.
13 (3) Pointer to RuntimeS structure.
14 (4) Pointer to ConfigS structure.
15 (5) Rotation angle.
16 (6) Rotation axis identifier (1 = x, 2 = y, 3 = z).
17
18 Output:
19 (1) Atoms rotated in all caught macromolecular complexes.
20
21 Return value:
22 (1) Edit mode index (positive or zero) on success.
23 (2) Negative on failure.
24
25 ========includes:============================================================*/
26
27 #include <stdio.h>
28
29 #include <math.h>
30
31 #include <X11/Xlib.h>
32 #include <X11/Xutil.h>
33 #include <X11/Xos.h>
34 #include <X11/Xatom.h>
35
36 #include "defines.h"
37 #include "typedefs.h"
38
39 /*======function prototypes:=================================================*/
40
41 int EditPhi_ (MolComplexS *, RuntimeS *, ConfigS *, double);
42 int EditPsi_ (MolComplexS *, RuntimeS *, ConfigS *, double);
43 int EditOmega_ (MolComplexS *, RuntimeS *, ConfigS *, double);
44 int EditBond_ (MolComplexS *, int, RuntimeS *, ConfigS *, double);
45 int EditChi1_ (MolComplexS *, RuntimeS *, ConfigS *, double);
46 int EditChi2_ (MolComplexS *, RuntimeS *, ConfigS *, double);
47 int PrepareStereoData_ (MolComplexS *, ConfigS *);
48 void RotatePlane_ (MolComplexS *, ConfigS *, double, int);
49 void RotateMembrane_ (MolComplexS *, ConfigS *, double, int);
50
51 /*======rotate all caught macromol. complexes:===============================*/
52
Rotate_(MolComplexS * mol_complexSP,int mol_complexesN,RuntimeS * runtimeSP,ConfigS * configSP,double rotation_angle,int axisID)53 int Rotate_ (MolComplexS *mol_complexSP, int mol_complexesN,
54 RuntimeS *runtimeSP, ConfigS *configSP,
55 double rotation_angle, int axisID)
56 {
57 MolComplexS *curr_mol_complexSP;
58 int edit_modeI;
59 int mol_complexI;
60 double cos_angle, sin_angle;
61 size_t atomsN, atomI;
62 AtomS *curr_atomSP;
63 double x0, y0, z0, x, y, z, x_new = 0.0, y_new = 0.0, z_new = 0.0;
64
65 /* Pointer to default macromolecular complex: */
66 curr_mol_complexSP = mol_complexSP + runtimeSP->default_complexI;
67
68 /* Copy the edit mode index: */
69 edit_modeI = runtimeSP->edit_modeI;
70
71 /* Check the axis identifier and edit mode index. */
72
73 /* If axisID is three and edit_modeI is two, three, four or */
74 /* six, edit phi, psi, omega or selected side chain bond: */
75 if ((axisID == 3) &&
76 ((edit_modeI == 2) || (edit_modeI == 3) ||
77 (edit_modeI == 4) || (edit_modeI == 6)))
78 {
79 /* Edit phi: */
80 if (edit_modeI == 2)
81 {
82 EditPhi_ (curr_mol_complexSP,
83 runtimeSP, configSP,
84 rotation_angle);
85 }
86
87 /* Edit psi: */
88 else if (edit_modeI == 3)
89 {
90 EditPsi_ (curr_mol_complexSP,
91 runtimeSP, configSP,
92 rotation_angle);
93 }
94
95 /* Edit omega: */
96 else if (edit_modeI == 4)
97 {
98 EditOmega_ (curr_mol_complexSP,
99 runtimeSP, configSP,
100 rotation_angle);
101 }
102
103 /* Edit some other bond (side chain): */
104 else if (edit_modeI == 6)
105 {
106 EditBond_ (curr_mol_complexSP,
107 runtimeSP->default_complexI,
108 runtimeSP, configSP,
109 rotation_angle);
110 }
111
112 /* Prepare the stereo data, update one */
113 /* flag and return the edit mode index: */
114 /* Prepare stereo data, if required: */
115 if (configSP->stereoF)
116 {
117 PrepareStereoData_ (curr_mol_complexSP, configSP);
118 }
119
120 /* Set the position_changedF: */
121 curr_mol_complexSP->position_changedF = 1;
122
123 /* Return the edit mode index: */
124 return edit_modeI;
125 }
126
127 /* If axis identifier is two and edit_modeI is five, edit phi: */
128 else if ((axisID == 2) && (edit_modeI == 5))
129 {
130 /* Edit phi: */
131 rotation_angle *= -1;
132 EditPhi_ (curr_mol_complexSP, runtimeSP, configSP, rotation_angle);
133
134 /* Prepare the stereo data, update one */
135 /* flag and return the edit mode index: */
136 /* Prepare stereo data, if required: */
137 if (configSP->stereoF)
138 {
139 PrepareStereoData_ (curr_mol_complexSP, configSP);
140 }
141
142 /* Set the position_changedF: */
143 curr_mol_complexSP->position_changedF = 1;
144
145 /* Return the edit mode index: */
146 return edit_modeI;
147 }
148
149 /* If axis identifier is two and edit_modeI is seven, edit chi1: */
150 else if ((axisID == 2) && (edit_modeI == 7))
151 {
152 /* Edit chi1: */
153 rotation_angle *= -1;
154 EditChi1_ (curr_mol_complexSP, runtimeSP, configSP, rotation_angle);
155
156 /* Prepare the stereo data, update one */
157 /* flag and return the edit mode index: */
158 /* Prepare stereo data, if required: */
159 if (configSP->stereoF)
160 {
161 PrepareStereoData_ (curr_mol_complexSP, configSP);
162 }
163
164 /* Set the position_changedF: */
165 curr_mol_complexSP->position_changedF = 1;
166
167 /* Return the edit mode index: */
168 return edit_modeI;
169 }
170
171 /* If axis identifier is one and edit_modeI is five, edit psi: */
172 else if ((axisID == 1) && (edit_modeI == 5))
173 {
174 /* Edit psi: */
175 rotation_angle *= -1;
176 EditPsi_ (curr_mol_complexSP, runtimeSP, configSP, rotation_angle);
177
178 /* Prepare the stereo data, update one */
179 /* flag and return the edit mode index: */
180 /* Prepare stereo data, if required: */
181 if (configSP->stereoF)
182 {
183 PrepareStereoData_ (curr_mol_complexSP, configSP);
184 }
185
186 /* Set the position_changedF: */
187 curr_mol_complexSP->position_changedF = 1;
188
189 /* Return the edit mode index: */
190 return edit_modeI;
191 }
192
193 /* If axis identifier is one and edit_modeI is seven, edit chi2: */
194 else if ((axisID == 1) && (edit_modeI == 7))
195 {
196 /* Edit chi2: */
197 rotation_angle *= -1;
198 EditChi2_ (curr_mol_complexSP, runtimeSP, configSP, rotation_angle);
199
200 /* Prepare the stereo data, update one */
201 /* flag and return the edit mode index: */
202 /* Prepare stereo data, if required: */
203 if (configSP->stereoF)
204 {
205 PrepareStereoData_ (curr_mol_complexSP, configSP);
206 }
207
208 /* Set the position_changedF: */
209 curr_mol_complexSP->position_changedF = 1;
210
211 /* Return the edit mode index: */
212 return edit_modeI;
213 }
214
215 /* If this point is reached, the entire structure should be rotated. */
216
217 /* Calculate cosine and sine of the rotation angle: */
218 cos_angle = cos (rotation_angle);
219 sin_angle = sin (rotation_angle);
220
221 /* If working in default mode, rotate the entire structure: */
222 for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
223 {
224 /* Pointer to the current macromolecular complex: */
225 curr_mol_complexSP = mol_complexSP + mol_complexI;
226
227 /* Check is the current macromolecular complex caught: */
228 if (curr_mol_complexSP->catchF == 0) continue;
229
230 /* Check is it necessary to rotate the plane: */
231 if (curr_mol_complexSP->move_bits & PLANE_MASK)
232 {
233 RotatePlane_ (curr_mol_complexSP, configSP,
234 rotation_angle, axisID);
235 }
236
237 /* Check is it necessary to rotate the membrane: */
238 if (curr_mol_complexSP->move_bits & MEMBRANE_MASK)
239 {
240 RotateMembrane_ (curr_mol_complexSP, configSP,
241 rotation_angle, axisID);
242 }
243
244 /* Check is it necessary to rotate the structure at all: */
245 if (!(curr_mol_complexSP->move_bits & STRUCTURE_MASK)) continue;
246
247 /* Copy the rotation center coordinates: */
248 x0 = curr_mol_complexSP->rotation_center_vectorS.x;
249 y0 = curr_mol_complexSP->rotation_center_vectorS.y;
250 z0 = curr_mol_complexSP->rotation_center_vectorS.z;
251
252 /* Number of atoms in a macromolecular complex: */
253 atomsN = curr_mol_complexSP->atomsN;
254
255 /* Scan all atoms in the current complex: */
256 for (atomI = 0; atomI < atomsN; atomI++)
257 {
258 /* Pointer to the current atom: */
259 curr_atomSP = curr_mol_complexSP->atomSP + atomI;
260
261 /* Coordinates relative to the rotation center: */
262 x = curr_atomSP->raw_atomS.x[0] - x0;
263 y = curr_atomSP->raw_atomS.y - y0;
264 z = curr_atomSP->raw_atomS.z[0] - z0;
265
266 /* Rotate these coordinates: */
267 switch (axisID)
268 {
269 /* Rotate around x: */
270 case 1:
271 x_new = x;
272 y_new = y * cos_angle - z * sin_angle;
273 z_new = y * sin_angle + z * cos_angle;
274 break;
275
276 /* Rotate around y: */
277 case 2:
278 x_new = x * cos_angle + z * sin_angle;
279 y_new = y;
280 z_new = -x * sin_angle + z * cos_angle;
281 break;
282
283 /* Rotate around z: */
284 case 3:
285 x_new = x * cos_angle - y * sin_angle;
286 y_new = x * sin_angle + y * cos_angle;
287 z_new = z;
288 break;
289
290 /* The impossible case: */
291 default:
292 ;
293 break;
294
295 }
296
297 /* Translate and store new coordinates: */
298 curr_atomSP->raw_atomS.x[0] = x_new + x0;
299 curr_atomSP->raw_atomS.y = y_new + y0;
300 curr_atomSP->raw_atomS.z[0] = z_new + z0;
301 }
302
303 /* Prepare stereo data, if required: */
304 if (configSP->stereoF)
305 {
306 PrepareStereoData_ (curr_mol_complexSP, configSP);
307 }
308
309 /* Set the position_changedF: */
310 curr_mol_complexSP->position_changedF = 1;
311 }
312
313 /* Return edit mode index: */
314 return edit_modeI;
315 }
316
317 /*===========================================================================*/
318
319
320