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