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