1
/* Copyright (C) 2000 Damir Zucic */
3
/*=============================================================================
8
Draw plane for each macromolecular complex. Only visible planes
12
(1) Pointer to MolComplexS structure.
13
(2) Number of macromolecular complexes.
14
(3) Pointer to ConfigS structure, with configuration data.
15
(4) Pointer to GUIS structure.
16
(5) Pointer to NearestAtomS structure, with information about the
17
atom occupying the given pixel.
18
(6) The number of pixels in the main window free area.
19
(7) The refreshI, used to check the NearestAtomS associated with
23
(1) Plane drawn for each macromolecular complex, if visible.
27
(1) Positive always (trivial).
30
(1) Indentation is exceptionally 4 spaces.
32
=============================================================================*/
39
#include <X11/Xutil.h>
41
#include <X11/Xatom.h>
46
/*======function prototypes:=================================================*/
48
void PlaneExtent_ (int *, int *, int *, int *,
49
PlaneS *, ConfigS *, int);
50
unsigned long WeightColors_ (unsigned long, unsigned long, double, GUIS *);
52
/*======draw planes:=========================================================*/
54
int DrawPlanes_ (MolComplexS *mol_complexSP, int mol_complexesN,
55
ConfigS *configSP, GUIS *guiSP,
56
NearestAtomS *nearest_atomSP, size_t pixelsN,
57
unsigned int refreshI)
61
MolComplexS *curr_mol_complexSP;
64
int center_screen_x, center_screen_y;
65
double angle, sin_angle, cos_angle;
66
double reciprocal_a, reciprocal_b;
67
double reciprocal_diameter;
69
int screen_x_min, screen_x_max, screen_y_min, screen_y_max;
70
int screen_x, screen_y;
71
double x_relative, y_relative, x_rotated, y_rotated;
72
double ratio_x, ratio_y, d;
73
double plane_delta_z, plane_z;
75
NearestAtomS *curr_pixelSP;
77
unsigned long plane_colorID, old_colorID, colorID;
79
/* Number of images: */
80
if (configSP->stereoF) imagesN = 2;
83
/* Draw plane, if visible, for each macromolecular complex: */
84
for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
86
/* Pointer to current macromolecular complex: */
87
curr_mol_complexSP = mol_complexSP + mol_complexI;
89
/* Prepare and check the number of atoms: */
90
atomsN = curr_mol_complexSP->atomsN;
91
if (atomsN == 0) continue;
93
/* Pointer to the current plane: */
94
curr_planeSP = &curr_mol_complexSP->planeS;
96
/* Check is the current plane hidden: */
97
if (curr_planeSP->hiddenF) continue;
99
/* Draw one image (mono) or two images (stereo): */
100
for (imageI = 0; imageI < imagesN; imageI++)
102
/* Plane center position: */
103
center_screen_x = curr_planeSP->center_screen_x[imageI];
104
center_screen_y = curr_planeSP->center_screen_y;
106
/* The shifted phi angle, used to rotate */
107
/* the rectangle bounding the ellipsa : */
108
angle = curr_planeSP->normal_phi[imageI] - 4.712389;
110
/* Sine and cosine of this angle: */
111
sin_angle = sin (angle);
112
cos_angle = cos (angle);
114
/* Reciprocal values of half axes: */
115
if (curr_planeSP->screen_a == 0.0) reciprocal_a = 0.0;
116
else reciprocal_a = 1.0 / curr_planeSP->screen_a;
117
if (curr_planeSP->screen_b[imageI] == 0.0) reciprocal_b = 0.0;
118
else reciprocal_b = 1.0 / curr_planeSP->screen_b[imageI];
120
/* Reciprocal diameter (required for color fading effect): */
121
if (curr_planeSP->circle_radius == 0.0) reciprocal_diameter = 0.0;
122
else reciprocal_diameter = 0.5 / curr_planeSP->circle_radius;
124
/* The coefficient used to calculate z value for a given pixel: */
125
if (curr_planeSP->screen_b[imageI] == 0.0) coeff = 0.0;
128
coeff = curr_planeSP->circle_radius *
129
sin (curr_planeSP->normal_theta[imageI]) /
130
curr_planeSP->screen_b[imageI];
131
if (curr_planeSP->normal_theta[imageI] >= 1.5707963) coeff *= -1;
134
/* Find the plane extent: */
135
PlaneExtent_ (&screen_x_min, &screen_x_max,
136
&screen_y_min, &screen_y_max,
137
curr_planeSP, configSP, imageI);
139
/* Scan the rectangle bounding ellipse: */
140
for (screen_x = screen_x_min; screen_x <= screen_x_max; screen_x++)
142
for (screen_y = screen_y_min; screen_y <= screen_y_max; screen_y++)
144
/* Pixel position relative to the plane center position: */
145
x_relative = screen_x - center_screen_x;
146
y_relative = screen_y - center_screen_y;
148
/* Rotated pixel position (rotation is anticlockwise here): */
149
x_rotated = x_relative * cos_angle + y_relative * sin_angle;
150
y_rotated = -x_relative * sin_angle + y_relative * cos_angle;
152
/* Check is it inside bounding ellipse: */
153
ratio_x = x_rotated * reciprocal_a;
154
ratio_y = y_rotated * reciprocal_b;
155
d = ratio_x * ratio_x + ratio_y * ratio_y;
156
if (d > 1.0) continue;
158
/* Calculate the z value for this pixel: */
159
plane_delta_z = coeff * y_rotated;
160
plane_z = curr_planeSP->center_z[imageI] + plane_delta_z;
162
/* The current pixel index: */
163
pixelI = guiSP->main_win_free_area_width * screen_y + screen_x;
165
/* Check pixel index: */
166
if (pixelI >= pixelsN) continue;
168
/* Pointer to NearestAtomS struct. */
169
/* assigned to current coordinates: */
170
curr_pixelSP = nearest_atomSP + pixelI;
172
/* If something was drawn to the current */
173
/* pixel in this step, compare z values: */
174
if (curr_pixelSP->last_refreshI == refreshI)
176
/* If the point drawn before is closer to the */
177
/* observer than plane, do not draw anything: */
178
if (curr_pixelSP->z < plane_z)
183
/* If the plane is closer than the */
184
/* point drawn before, mix colors: */
187
/* The plane color: */
188
scale_factor = (plane_delta_z +
189
curr_planeSP->circle_radius) *
191
if (scale_factor < 0.0) scale_factor = 0.0;
192
if (scale_factor > 1.0) scale_factor = 1.0;
193
if (curr_planeSP->visible_sideI[imageI] == 0)
195
plane_colorID = WeightColors_ (
196
curr_planeSP->top_near_colorID,
197
curr_planeSP->top_far_colorID,
198
scale_factor, guiSP);
202
plane_colorID = WeightColors_ (
203
curr_planeSP->bottom_near_colorID,
204
curr_planeSP->bottom_far_colorID,
205
scale_factor, guiSP);
208
/* The color of the object which was */
209
/* drawn before the current plane: */
210
old_colorID = curr_pixelSP->colorID;
212
/* The weighting factor which should be used */
213
/* to mix the plane color and the old color: */
214
scale_factor = curr_planeSP->transparency;
216
/* Mix the plane color and the old color: */
217
colorID = WeightColors_ (plane_colorID,
219
scale_factor, guiSP);
223
/* If nothing was drawn to the current pixel */
224
/* in this drawing step, prepare the color: */
227
/* Prepare the scale factor used to weight (mix) colors: */
228
scale_factor = (plane_delta_z +
229
curr_planeSP->circle_radius) *
231
if (scale_factor < 0.0) scale_factor = 0.0;
232
if (scale_factor > 1.0) scale_factor = 1.0;
234
/* Prepare the color by weighting */
235
/* (mixing) near and far color: */
236
if (curr_planeSP->visible_sideI[imageI] == 0)
238
colorID = WeightColors_ (
239
curr_planeSP->top_near_colorID,
240
curr_planeSP->top_far_colorID,
241
scale_factor, guiSP);
245
colorID = WeightColors_ (
246
curr_planeSP->bottom_near_colorID,
247
curr_planeSP->bottom_far_colorID,
248
scale_factor, guiSP);
251
/* Set the style index associated with the current pixel */
252
/* to signal that only plane was drawn to this pixel: */
253
curr_pixelSP->styleI = PLANE_STYLE;
257
XSetForeground (guiSP->displaySP, guiSP->theGCA[0], colorID);
258
XDrawPoint (guiSP->displaySP, guiSP->main_hidden_pixmapID,
259
guiSP->theGCA[0], screen_x, screen_y);
261
/* Update refresh index, z value and */
262
/* color value for the current pixel: */
263
curr_pixelSP->last_refreshI = refreshI;
264
curr_pixelSP->z = plane_z;
265
curr_pixelSP->colorID = colorID;
271
/* Return positive value (trivial): */
275
/*===========================================================================*/