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