1 /* Copyright (C) 2000-2002 Damir Zucic */
2
3 /*=============================================================================
4
5 bond_style3_quad4.c
6
7 Purpose:
8 Draw bond which fits into quadrant 4 using style 3. See the file
9 file bonds_style3.c for description of quadrants.
10
11 Input:
12 (1) Pointer to Aux1S structure, which contains required data.
13 (2) Bond index.
14
15 Output:
16 (1) A single bond drawn.
17 (2) Return value.
18
19 Return value:
20 (1) One if at least one pixel is drawn.
21 (2) Zero otherwise.
22
23 =============================================================================*/
24
25 #include <stdio.h>
26
27 #include <math.h>
28
29 #include <X11/Xlib.h>
30 #include <X11/Xutil.h>
31 #include <X11/Xos.h>
32 #include <X11/Xatom.h>
33
34 #include "defines.h"
35 #include "typedefs.h"
36
37 /*======draw bond in quadrant 4 using style 3:===============================*/
38
BondStyle3Quadrant4_(Aux1S * aux1SP,int bondI)39 int BondStyle3Quadrant4_ (Aux1S *aux1SP, int bondI)
40 {
41 long pixels_drawnN = 0;
42 double recip_denom, y_to_x_scale, y_to_z_scale;
43 int screen_x, line_screen_x, screen_y, screen_y1, delta_y;
44 double d, atomic_z;
45 int lineI;
46 size_t pixelI;
47 NearestAtomS *curr_pixelSP;
48
49 /* Scale factor required to calculate screen_x from screen_y: */
50 if (aux1SP->screen_delta_y != 0)
51 recip_denom = 1.0 / (double) aux1SP->screen_delta_y;
52 else recip_denom = 0.0;
53 y_to_x_scale = (double) aux1SP->screen_delta_x * recip_denom;
54
55 /* Scale factor required to calculate z (in atomic units) from screen_y: */
56 y_to_z_scale = aux1SP->atomic_delta_z * recip_denom;
57
58 /* Vertical scan (bottom to top): */
59 screen_y1 = (aux1SP->screen_y0 + aux1SP->screen_y1) / 2;
60 for (screen_y = aux1SP->screen_y0; screen_y >= screen_y1; screen_y--)
61 {
62 /* Check is this pixel inside the area reserved for the */
63 /* current image (there are two images in stereo mode): */
64 if (screen_y < aux1SP->configSP->image_screen_y0) continue;
65 if (screen_y > aux1SP->configSP->image_screen_y1) continue;
66
67 /* Relative position: */
68 delta_y = screen_y - aux1SP->screen_y0;
69
70 /* Find the corresponding screen_x: */
71 d = (double) aux1SP->screen_x0 + y_to_x_scale * (double) delta_y;
72 screen_x = (int) (d + 0.5);
73
74 /* z value (in atomic units): */
75 atomic_z = aux1SP->atomic_z0 + y_to_z_scale * (double) delta_y;
76
77 /* Loop which draws five lines (horizontal scan): */
78 for (lineI = 0; lineI <= 4; lineI++)
79 {
80 /* Pixel position: */
81 line_screen_x = screen_x +lineI - 2;
82
83 /* Check is this pixel inside the area reserved for the */
84 /* current image (there are two images in stereo mode): */
85 if (line_screen_x <
86 aux1SP->configSP->image_screen_x0[aux1SP->imageI])
87 {
88 continue;
89 }
90 if (line_screen_x >
91 aux1SP->configSP->image_screen_x1[aux1SP->imageI])
92 {
93 continue;
94 }
95
96 /* Current pixel index: */
97 pixelI = aux1SP->guiSP->main_win_free_area_width * screen_y +
98 line_screen_x;
99
100 /* Check pixel index: */
101 if (pixelI >= aux1SP->pixelsN) break;
102
103 /* Pointer to NearestAtomS struct. */
104 /* assigned to current coordinates: */
105 curr_pixelSP = aux1SP->nearest_atomSP + pixelI;
106
107 /* Check was this pixel used already in */
108 /* this drawing step; if it was, compare */
109 /* the z value of the current atom with z */
110 /* value previously stored to this pixel: */
111 if (aux1SP->refreshI == curr_pixelSP->last_refreshI)
112 {
113 if (atomic_z >= curr_pixelSP->z) continue;
114 }
115
116 /* If this point is reached draw pixel: */
117 XDrawPoint (aux1SP->guiSP->displaySP,
118 aux1SP->guiSP->main_hidden_pixmapID,
119 aux1SP->guiSP->theGCA[lineI],
120 line_screen_x, screen_y);
121
122 /* Refresh the content of NearestAtomS */
123 /* array associated with this pixel: */
124 curr_pixelSP->styleI = 3;
125 curr_pixelSP->last_refreshI = aux1SP->refreshI;
126 curr_pixelSP->mol_complexI = aux1SP->mol_complexI;
127 curr_pixelSP->atomI = aux1SP->atomI;
128 curr_pixelSP->bondI = bondI;
129 curr_pixelSP->z = atomic_z;
130 curr_pixelSP->colorID = aux1SP->colorIDA[lineI];
131
132 /* Update the number of pixels drawn: */
133 pixels_drawnN++;
134 }
135 }
136
137 /* Rounding the bottom end: */
138 do
139 {
140 /* The y coordinate: */
141 screen_y = aux1SP->screen_y0 + 1;
142
143 /* Check: */
144 if (screen_y < aux1SP->configSP->image_screen_y0) break;
145 if (screen_y > aux1SP->configSP->image_screen_y1) break;
146
147 /* z value (in atomic units): */
148 atomic_z = aux1SP->atomic_z0;
149
150 /* The x coordinate of central pixel: */
151 screen_x = aux1SP->screen_x0;
152
153 /* Scan three lines: */
154 for (lineI = 0; lineI <= 2; lineI++)
155 {
156 /* Pixel position: */
157 line_screen_x = screen_x +lineI - 1;
158
159 /* Check: */
160 if (line_screen_x <
161 aux1SP->configSP->image_screen_x0[aux1SP->imageI])
162 {
163 continue;
164 }
165 if (line_screen_x >
166 aux1SP->configSP->image_screen_x1[aux1SP->imageI])
167 {
168 continue;
169 }
170
171 /* Current pixel index: */
172 pixelI = aux1SP->guiSP->main_win_free_area_width * screen_y +
173 line_screen_x;
174
175 /* Check pixel index: */
176 if (pixelI >= aux1SP->pixelsN) break;
177
178 /* Pointer to NearestAtomS struct. */
179 /* assigned to current coordinates: */
180 curr_pixelSP = aux1SP->nearest_atomSP + pixelI;
181
182 /* Check was this pixel used already in this drawing step : */
183 if (aux1SP->refreshI == curr_pixelSP->last_refreshI)
184 {
185 if (atomic_z >= curr_pixelSP->z) continue;
186 }
187
188 /* If this point is reached draw one pixel: */
189 XDrawPoint (aux1SP->guiSP->displaySP,
190 aux1SP->guiSP->main_hidden_pixmapID,
191 aux1SP->guiSP->theGCA[lineI + 1],
192 line_screen_x, screen_y);
193
194 /* Refresh the content of NearestAtomS */
195 /* array associated with this pixel: */
196 curr_pixelSP->styleI = 3;
197 curr_pixelSP->last_refreshI = aux1SP->refreshI;
198 curr_pixelSP->mol_complexI = aux1SP->mol_complexI;
199 curr_pixelSP->atomI = aux1SP->atomI;
200 curr_pixelSP->bondI = bondI;
201 curr_pixelSP->z = atomic_z;
202 curr_pixelSP->colorID = aux1SP->colorIDA[lineI + 1];
203
204 /* Update the number of pixels drawn: */
205 pixels_drawnN++;
206 }
207
208 /* End of single pass loop: */
209 } while (0);
210
211 /* Rounding the top end: */
212 do
213 {
214 /* The y coordinate: */
215 screen_y = screen_y1 - 1;
216
217 /* Check: */
218 if (screen_y < aux1SP->configSP->image_screen_y0) break;
219 if (screen_y > aux1SP->configSP->image_screen_y1) break;
220
221 /* Relative position: */
222 delta_y = screen_y1 - aux1SP->screen_y0;
223
224 /* z value (in atomic units): */
225 atomic_z = aux1SP->atomic_z0 + y_to_z_scale * (double) delta_y;
226
227 /* The x coordinate of central pixel: */
228 d = (double) aux1SP->screen_x0 + y_to_x_scale * (double) delta_y;
229 screen_x = (int) (d + 0.5);
230
231 /* Scan three lines: */
232 for (lineI = 0; lineI <= 2; lineI++)
233 {
234 /* Pixel position: */
235 line_screen_x = screen_x +lineI - 1;
236
237 /* Check: */
238 if (line_screen_x <
239 aux1SP->configSP->image_screen_x0[aux1SP->imageI])
240 {
241 continue;
242 }
243 if (line_screen_x >
244 aux1SP->configSP->image_screen_x1[aux1SP->imageI])
245 {
246 continue;
247 }
248
249 /* Current pixel index: */
250 pixelI = aux1SP->guiSP->main_win_free_area_width * screen_y +
251 line_screen_x;
252
253 /* Check pixel index: */
254 if (pixelI >= aux1SP->pixelsN) break;
255
256 /* Pointer to NearestAtomS struct. */
257 /* assigned to current coordinates: */
258 curr_pixelSP = aux1SP->nearest_atomSP + pixelI;
259
260 /* Check was this pixel used already in this drawing step : */
261 if (aux1SP->refreshI == curr_pixelSP->last_refreshI)
262 {
263 if (atomic_z >= curr_pixelSP->z) continue;
264 }
265
266 /* If this point is reached draw one pixel: */
267 XDrawPoint (aux1SP->guiSP->displaySP,
268 aux1SP->guiSP->main_hidden_pixmapID,
269 aux1SP->guiSP->theGCA[lineI + 1],
270 line_screen_x, screen_y);
271
272 /* Refresh the content of NearestAtomS */
273 /* array associated with this pixel: */
274 curr_pixelSP->styleI = 3;
275 curr_pixelSP->last_refreshI = aux1SP->refreshI;
276 curr_pixelSP->mol_complexI = aux1SP->mol_complexI;
277 curr_pixelSP->atomI = aux1SP->atomI;
278 curr_pixelSP->bondI = bondI;
279 curr_pixelSP->z = atomic_z;
280 curr_pixelSP->colorID = aux1SP->colorIDA[lineI + 1];
281
282 /* Update the number of pixels drawn: */
283 pixels_drawnN++;
284 }
285
286 /* End of single pass loop: */
287 } while (0);
288
289 /* Check is at least one pixel drawn: */
290 if (pixels_drawnN > 0) return 1;
291
292 /* If this point is reached, nothing is drawn: */
293 return 0;
294 }
295
296 /*===========================================================================*/
297
298
299