1 // $Id: cursor.cxx 1003 2010-08-23 21:45:23Z martin $
2 //
3 // cursor.cxx - routine for DRAWxtl V5.5 - the GUI version
4 //
5 // Coded using the FLTK 1.1.6 widget set
6 //
7 // Larry W. Finger, Martin Kroeker and Brian Toby
8 //
9 // This module includes cursor support routines
10 //
11 // routines contained within this file:
12 //
13 // display_cursor_text - output the cursor position into the status line
14 // draw_cursor - put the cursor on the screen
15 // find_atom - find atom nearest the cursor position
16 // find_proj_atom - find atom that projects closest to the cursor
17 // move_cursor - move the cursor position
18
19 #include "drawxtl.h"
20 #include <stdio.h>
21 #include <string.h>
22 #include <math.h>
23 #include <stdlib.h>
24 #include "draw_ext.h"
25 #include <FL/x.H>
26 #include "DRAWxtlViewUI.h"
27 #include "CrystalView.h"
28
29 #include "DRAWxtl_proto.h"
30
31 void
display_cursor_text(void)32 display_cursor_text (void)
33 {
34 char Text[500];
35
36 char text[100];
37
38 char text2[100];
39
40 char Text2[100];
41
42 char Text3[100];
43
44 if (!cur_show)
45 return;
46
47 strcpy (Text2, "");
48 strcpy (Text3, "");
49 if (!ReadFourMap)
50 sprintf (Text, " Cursor: %.4f,%.4f,%.4f (step=%.2fA)",
51 cur_cen[0], cur_cen[1], cur_cen[2], drvui->cur_step);
52 else
53 sprintf (Text, " Cursor: %.4f,%.4f,%.4f (step=%.2fA). Rho=%.3f",
54 cur_cen[0], cur_cen[1], cur_cen[2], drvui->cur_step,
55 InterpolateMap (cur_cen[0], cur_cen[1], cur_cen[2]));
56 if (cur_atom[0] > 0) {
57 sprintf (Text2, " Atoms 1.%s", cur_name[0]);
58 }
59 if (cur_atom[1] > 0) {
60 sprintf (text2, " 2.%s", cur_name[1]);
61 strcat (Text2, text2);
62 sprintf (Text3, "\n d12=%6.3fA", dist12);
63 if (cur_atom[2] > 0) {
64 sprintf (text2, " 3.%s", cur_name[2]);
65 strcat (Text2, text2);
66 sprintf (text, ", d23=%6.3fA, a123=%5.2f�", dist23, ang123);
67 strcat (Text3, text);
68 if (cur_atom[3] > 0) {
69 sprintf (text2, " 4.%s", cur_name[3]);
70 strcat (Text2, text2);
71 sprintf (text, ", d34=%6.3fA, a234=%5.2f�, tor1234=%5.2f�", dist34,
72 ang234, torsion_ang);
73 strcat (Text3, text);
74 }
75 }
76 }
77 strcat (Text, Text2);
78 strcat (Text, Text3);
79 drvui->Cursor_pos->value (Text);
80
81 if (drvui->Cursor_posW)
82 update_cursor_window ();
83 }
84
85 void
draw_cursor(void)86 draw_cursor (void)
87 {
88
89 int i, j;
90
91 float vert[3];
92
93 if (!cur_show)
94 return;
95
96 nvert = 0; /* initialize vertex list */
97 for (i = 0; i <= 2; ++i) {
98 for (j = 0; j < 3; j++)
99 vert[j] = cur_cen[j];
100 vert[i] = cur_cen[i] - 0.5f / drvui->lat_con[i];
101 add_vert_nc (vert);
102 vert[i] = cur_cen[i] + 0.5f / drvui->lat_con[i];
103 add_vert_nc (vert);
104 }
105 glPushMatrix ();
106 glDisable (GL_LIGHTING);
107 glColor3f (1.0, 0.0, 0.0);
108
109 glBegin (GL_LINES);
110 glVertex3f (s_vert[0], s_vert[1], s_vert[2]);
111 glVertex3f (s_vert[3], s_vert[4], s_vert[5]);
112
113 glVertex3f (s_vert[6], s_vert[7], s_vert[8]);
114 glVertex3f (s_vert[9], s_vert[10], s_vert[11]);
115
116 glVertex3f (s_vert[12], s_vert[13], s_vert[14]);
117 glVertex3f (s_vert[15], s_vert[16], s_vert[17]);
118 glEnd ();
119 glEnable (GL_LIGHTING);
120
121 glPopMatrix ();
122 }
123
124
125 int
find_atom(void)126 find_atom (void)
127 {
128 int i, j;
129
130 double distance = 1000.0, d;
131
132 int closest = 0;
133
134 nvert = 0;
135 for (i = 0; i < natom; i++)
136 find_all_in_box (i);
137
138 for (j = 0; j < nvert; j++) {
139 d = (o_vert[3 * j] - cur_cen[0]) * (o_vert[3 * j] - cur_cen[0])
140 + (o_vert[3 * j + 1] - cur_cen[1]) * (o_vert[3 * j + 1] - cur_cen[1])
141 + (o_vert[3 * j + 2] - cur_cen[2]) * (o_vert[3 * j + 2] - cur_cen[2]);
142 if (d < distance) {
143 distance = d;
144 closest = j;
145 }
146 }
147 cur_cen[0] = o_vert[3 * closest];
148 cur_cen[1] = o_vert[3 * closest + 1];
149 cur_cen[2] = o_vert[3 * closest + 2];
150 return closest;
151 }
152
153 int
find_proj_atom(int x,int y)154 find_proj_atom (int x, int y)
155 {
156 int j, k;
157
158 double distance = 1.0e15, d;
159
160 int closest = 0;
161
162 int clipped = 0;
163
164 GLdouble winX, winY, winZ;
165
166 int saved_nvert = nvert;
167
168 for (j = 0; j < natom; ++j) { // get all atoms in display box
169 find_all_in_box (j);
170 }
171 for (j = saved_nvert; j < nvert; j++) { // loop through all atoms
172 clipped = 0;
173 if (clipflag == 1) {
174 for (k = 0; k < 3; k++)
175 if (o_vert[3 * j + k] < drvui->frames[drvui->frame_no].clip_lim[k] - 0.01f
176 || o_vert[3 * j + k] >
177 drvui->frames[drvui->frame_no].clip_lim[k + 3] + 0.01f)
178 clipped = 1;
179 }
180 if (clipped == 1)
181 continue;
182 gluProject (s_vert[3 * j], s_vert[3 * j + 1], s_vert[3 * j + 2],
183 modelMatrix, projMatrix, viewport, &winX, &winY, &winZ);
184 d = ((float) x - winX) * ((float) x - winX) +
185 ((float) y + winY - viewport[3]) * ((float) y + winY - viewport[3]);
186 if (d < distance) { // find closest atom (in projection
187 distance = d;
188 closest = j;
189 }
190 }
191 nvert = saved_nvert;
192 cur_cen[0] = o_vert[3 * closest]; // set cursor to atom coordinates
193 cur_cen[1] = o_vert[3 * closest + 1];
194 cur_cen[2] = o_vert[3 * closest + 2];
195
196 return closest;
197 }
198
199 void
move_cursor(int axis,float inc_amt)200 move_cursor (int axis, float inc_amt)
201 {
202 if (!cur_show)
203 return;
204
205 // cur_name[0][0] = '\0';
206 cur_cen[axis] += inc_amt * drvui->cur_step / drvui->lat_con[axis];
207 }
208
209 void
update_cursor_window(void)210 update_cursor_window (void)
211 {
212 char string[100], string2[30];
213
214 float centr2[3] = {0.0f, 0.0f, 0.0f}, centr3[3] = {0.0f, 0.0f, 0.0f}, centr4[3] = {0.0f,0.0f,0.0f};
215
216 int lastatom, i;
217
218 float dist1 = 0.0f, dist2 = 0.0f, dist3 = 0.0f;
219
220 float ang1 = 0.0f, ang2 = 0.0f;
221
222 drvui->Cursor_posW->clear();
223
224 if (!cur_show) {
225 sprintf (string, "Press 'c' to activate the cursor mode in the graphics area");
226 drvui->Cursor_posW->add (string);
227 return;
228 }
229
230 sprintf (string, "Cursor position:\t\t%.4f\t%.4f\t%.4f",
231 cur_cen[0], cur_cen[1], cur_cen[2]);
232 drvui->Cursor_posW->add (string);
233 sprintf (string, "Current step size\t%.2fA", drvui->cur_step);
234 drvui->Cursor_posW->add (string);
235
236 if (ReadFourMap) {
237 sprintf (string, "Local rho value\t\t\t%.3f",
238 InterpolateMap (cur_cen[0], cur_cen[1], cur_cen[2]));
239 drvui->Cursor_posW->add (string);
240 }
241
242 drvui->Cursor_posW->add ("\n");
243
244 lastatom = -1;
245 for (i = 0; i < 4; i++)
246 if (cur_atom[i] > 0) lastatom++;
247
248 switch (lastatom) {
249 case 3:
250 dist1=dist34;
251 dist2=dist23;
252 dist3=dist12;
253 ang1=ang234;
254 ang2=ang123;
255 break;
256 case 2:
257 dist1=dist23;
258 dist2=dist12;
259 ang1=ang123;
260 break;
261 case 1:
262 dist1=dist12;
263 break;
264 default:
265 break;
266 }
267 if (lastatom > -1) {
268 sprintf (string, "Current atom:\t%4s\t%.4f\t%.4f\t%.4f", cur_name[lastatom],
269 o_vert[3 * cur_atom[lastatom]], o_vert[3 * cur_atom[lastatom] + 1],
270 o_vert[3 * cur_atom[lastatom] + 2]);
271 drvui->Cursor_posW->add (string);
272 }
273 strcpy (string,"\n");
274 drvui->Cursor_posW->add (string);
275 drvui->Cursor_posW->add ("@-");
276 drvui->Cursor_posW->add (string);
277
278 if (lastatom > 0) {
279 sprintf (string, "Distance\t%4s-%4s\t\t\t%.3f",cur_name[lastatom],cur_name[lastatom-1],dist1);
280 drvui->Cursor_posW->add (string);
281 }
282 if (lastatom > 1) {
283 sprintf (string, "Angle\t%4s-%4s\t-%4s\t\t%.3f",cur_name[lastatom],cur_name[lastatom-1],cur_name[lastatom-2],ang1);
284 drvui->Cursor_posW->add (string);
285 }
286 if (cur_atom[3] > 0) {
287 sprintf (string, "Dihedral angle\t%4s-%4s\t-%4s\t-%4s\t%.3f", cur_name[3],
288 cur_name[2], cur_name[1], cur_name[0], torsion_ang);
289 drvui->Cursor_posW->add (string);
290 sprintf (string, "Distance\t%4s-%4s\t\t\t%.3f", cur_name[1], cur_name[2], dist23);
291 drvui->Cursor_posW->add (string);
292 sprintf (string, "Distance\t%4s-%4s\t\t\t%.3f", cur_name[1], cur_name[0], dist12);
293 drvui->Cursor_posW->add (string);
294 sprintf (string, "Angle\t%4s-%4s\t-%4s\t\t%.3f", cur_name[2], cur_name[1], cur_name[0],
295 ang2);
296 drvui->Cursor_posW->add (string);
297 } else if (cur_atom[2] > 0) {
298 sprintf (string, "Distance\t%4s-%4s\t\t\t%.3f", cur_name[1], cur_name[2], dist23);
299 drvui->Cursor_posW->add (string);
300 }
301
302 strcpy (string, "\n");
303 drvui->Cursor_posW->add (string);
304 drvui->Cursor_posW->add ("@-");
305 drvui->Cursor_posW->add (string);
306
307 if (lastatom > 0) {
308 sprintf (string, "Distance Matrix\t%4s\t%4s",
309 cur_name[lastatom], cur_name[lastatom - 1]);
310 if (lastatom > 1) {
311 sprintf (string2, "\t%4s", cur_name[lastatom - 2]);
312 strcat (string, string2);
313 }
314 if (lastatom > 2) {
315 sprintf (string2, "\t%4s", cur_name[lastatom - 3]);
316 strcat (string, string2);
317 }
318 drvui->Cursor_posW->add (string);
319 sprintf (string, "%4s\t-\t%5.3f", cur_name[lastatom], dist1);
320 if (lastatom > 1) {
321 sprintf (string2, "\t%5.3f", dist (cur_atom[lastatom], cur_atom[lastatom - 2]));
322 strcat (string, string2);
323 }
324 if (lastatom > 2) {
325 sprintf(string2, "\t%5.3f", dist(cur_atom[lastatom],cur_atom[lastatom - 3]));
326 strcat (string, string2);
327 }
328 drvui->Cursor_posW->add (string);
329 centr2[0] = (o_vert[3 * cur_atom[lastatom]] + o_vert[3 * cur_atom[lastatom - 1]]) / 2.0f;
330 centr2[1] = (o_vert[3 * cur_atom[lastatom] + 1] + o_vert[3 * cur_atom[lastatom - 1] + 1] ) / 2.0f;
331 centr2[2] = (o_vert[3 * cur_atom[lastatom] + 2] + o_vert[3 * cur_atom[lastatom - 1] + 2] ) / 2.0f;
332 }
333
334 if (lastatom > 1) {
335 sprintf (string, "%4s\t%.3f\t-\t%.3f",
336 cur_name[lastatom - 1], dist1, dist2);
337 if (lastatom > 2) {
338 sprintf (string2, "\t%5.3f", dist (cur_atom[lastatom - 1], cur_atom[lastatom - 3 ]));
339 strcat (string, string2);
340 }
341 drvui->Cursor_posW->add (string);
342
343 sprintf (string, "%4s\t%.3f\t%.3f\t-",
344 cur_name[lastatom - 2], dist (cur_atom[lastatom], cur_atom[lastatom - 2]), dist (cur_atom[lastatom - 1], cur_atom[lastatom - 2 ]));
345 if (lastatom > 2) {
346 sprintf (string2, "\t%.3f", dist3);
347 strcat (string, string2);
348 }
349 drvui->Cursor_posW->add (string);
350
351 centr3[0] = (o_vert[3 * cur_atom[lastatom]] + o_vert[3 * cur_atom[lastatom - 1]]
352 + o_vert[3 * cur_atom[lastatom - 2]]) / 3.0f;
353 centr3[1] = (o_vert[3 * cur_atom[lastatom] + 1] + o_vert[3 * cur_atom[lastatom - 1] + 1]
354 + o_vert[3 * cur_atom[lastatom - 2] + 1]) / 3.0f;
355 centr3[2] = (o_vert[3 * cur_atom[lastatom] + 2] + o_vert[3 * cur_atom[lastatom - 1] + 2]
356 + o_vert[3 * cur_atom[lastatom - 2] + 2]) / 3.0f;
357 }
358 if (lastatom > 2) {
359 sprintf (string, "%4s\t%.3f\t%.3f\t%.3f\t-", cur_name[0],
360 dist(cur_atom[lastatom], cur_atom[lastatom - 3]),
361 dist(cur_atom[lastatom - 1], cur_atom[lastatom - 3]), dist3 );
362 drvui->Cursor_posW->add (string);
363
364 centr4[0] = (o_vert[3 * cur_atom[0]] + o_vert[3 * cur_atom[1]] + o_vert[3 * cur_atom[2]]
365 + o_vert[3 * cur_atom[3]]) / 4.0f;
366 centr4[1] = (o_vert[3 * cur_atom[0] + 1] + o_vert[3 * cur_atom[1] + 1]
367 + o_vert[3 * cur_atom[2] + 1] + o_vert[3 * cur_atom[3] + 1]) / 4.0f;
368 centr4[2] = (o_vert[3 * cur_atom[0] + 2] + o_vert[3 * cur_atom[1] + 2]
369 + o_vert[3 * cur_atom[2] + 2] + o_vert[3 * cur_atom[3] + 2]) / 4.0f;
370 }
371 strcpy (string, "\n");
372 drvui->Cursor_posW->add (string);
373 drvui->Cursor_posW->add ("@-");
374 drvui->Cursor_posW->add (string);
375 if (cur_atom[1] > 0) {
376 sprintf (string, "Center of top 2 atoms\t\t%.4f\t%.4f\t%.4f",
377 centr2[0], centr2[1], centr2[2]);
378 drvui->Cursor_posW->add (string);
379 }
380 if (cur_atom[2] > 0) {
381 sprintf (string, "Center of top 3 atoms\t\t%.4f\t%.4f\t%.4f",
382 centr3[0], centr3[1], centr3[2]);
383 drvui->Cursor_posW->add (string);
384 }
385 if (cur_atom[3] > 0) {
386 sprintf (string, "Center of all 4 atoms\t\t%.4f\t%.4f\t%.4f",
387 centr4[0], centr4[1], centr4[2]);
388 drvui->Cursor_posW->add (string);
389 }
390 }
391