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