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