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