~ubuntu-branches/ubuntu/breezy/garlic/breezy

« back to all changes in this revision

Viewing changes to draw_planes.c

  • Committer: Bazaar Package Importer
  • Author(s): zhaoway
  • Date: 2001-04-24 07:09:13 UTC
  • Revision ID: james.westby@ubuntu.com-20010424070913-uzpupnwdfhmliebz
Tags: upstream-1.1
ImportĀ upstreamĀ versionĀ 1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 Damir Zucic */
 
2
 
 
3
/*=============================================================================
 
4
 
 
5
                                draw_planes.c
 
6
 
 
7
Purpose:
 
8
        Draw plane  for each macromolecular complex.  Only visible planes
 
9
        will be drawn.
 
10
 
 
11
Input:
 
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
 
20
            a given pixel.
 
21
 
 
22
Output:
 
23
        (1) Plane drawn for each macromolecular complex, if visible.
 
24
        (2) Return value.
 
25
 
 
26
Return value:
 
27
        (1) Positive always (trivial).
 
28
 
 
29
Notes:
 
30
        (1) Indentation is exceptionally 4 spaces.
 
31
 
 
32
=============================================================================*/
 
33
 
 
34
#include <stdio.h>
 
35
 
 
36
#include <math.h>
 
37
 
 
38
#include <X11/Xlib.h>
 
39
#include <X11/Xutil.h>
 
40
#include <X11/Xos.h>
 
41
#include <X11/Xatom.h>
 
42
 
 
43
#include "defines.h"
 
44
#include "typedefs.h"
 
45
 
 
46
/*======function prototypes:=================================================*/
 
47
 
 
48
void            PlaneExtent_ (int *, int *, int *, int *,
 
49
                              PlaneS *, ConfigS *, int);
 
50
unsigned long   WeightColors_ (unsigned long, unsigned long, double, GUIS *);
 
51
 
 
52
/*======draw planes:=========================================================*/
 
53
 
 
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)
 
58
{
 
59
int             imagesN, imageI;
 
60
int             mol_complexI;
 
61
MolComplexS     *curr_mol_complexSP;
 
62
size_t          atomsN;
 
63
PlaneS          *curr_planeSP;
 
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;
 
68
double          coeff;
 
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;
 
74
size_t          pixelI;
 
75
NearestAtomS    *curr_pixelSP;
 
76
double          scale_factor;
 
77
unsigned long   plane_colorID, old_colorID, colorID;
 
78
 
 
79
/* Number of images: */
 
80
if (configSP->stereoF) imagesN = 2;
 
81
else imagesN = 1;
 
82
 
 
83
/* Draw plane, if visible, for each macromolecular complex: */
 
84
for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
 
85
    {
 
86
    /* Pointer to current macromolecular complex: */
 
87
    curr_mol_complexSP = mol_complexSP + mol_complexI;
 
88
 
 
89
    /* Prepare and check the number of atoms: */
 
90
    atomsN = curr_mol_complexSP->atomsN;
 
91
    if (atomsN == 0) continue;
 
92
 
 
93
    /* Pointer to the current plane: */
 
94
    curr_planeSP = &curr_mol_complexSP->planeS;
 
95
 
 
96
    /* Check is the current plane hidden: */
 
97
    if (curr_planeSP->hiddenF) continue;
 
98
 
 
99
    /* Draw one image (mono) or two images (stereo): */
 
100
    for (imageI = 0; imageI < imagesN; imageI++)
 
101
        {
 
102
        /* Plane center position: */
 
103
        center_screen_x = curr_planeSP->center_screen_x[imageI];
 
104
        center_screen_y = curr_planeSP->center_screen_y;
 
105
 
 
106
        /* The shifted phi angle, used to rotate */
 
107
        /* the rectangle  bounding the ellipsa : */
 
108
        angle = curr_planeSP->normal_phi[imageI] - 4.712389;
 
109
 
 
110
        /* Sine and cosine of this angle: */
 
111
        sin_angle = sin (angle);
 
112
        cos_angle = cos (angle);
 
113
 
 
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];
 
119
 
 
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;
 
123
 
 
124
        /* The coefficient used to calculate z value for a given pixel: */
 
125
        if (curr_planeSP->screen_b[imageI] == 0.0) coeff = 0.0;
 
126
        else
 
127
            {
 
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;
 
132
            }
 
133
 
 
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);
 
138
 
 
139
        /* Scan the rectangle bounding ellipse: */
 
140
        for (screen_x = screen_x_min; screen_x <= screen_x_max; screen_x++)
 
141
            {
 
142
            for (screen_y = screen_y_min; screen_y <= screen_y_max; screen_y++)
 
143
                {
 
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;
 
147
 
 
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;
 
151
 
 
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;
 
157
 
 
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;
 
161
 
 
162
                /* The current pixel index: */
 
163
                pixelI = guiSP->main_win_free_area_width * screen_y + screen_x;
 
164
 
 
165
                /* Check pixel index: */
 
166
                if (pixelI >= pixelsN) continue;
 
167
 
 
168
                /* Pointer to  NearestAtomS struct. */
 
169
                /* assigned to current coordinates: */
 
170
                curr_pixelSP = nearest_atomSP + pixelI;
 
171
 
 
172
                /* If something was drawn to the current */
 
173
                /* pixel in this step, compare z values: */
 
174
                if (curr_pixelSP->last_refreshI == refreshI)
 
175
                    {
 
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)
 
179
                        {
 
180
                        continue;
 
181
                        }
 
182
 
 
183
                    /* If the plane is closer than the */
 
184
                    /* point drawn before, mix colors: */
 
185
                    else
 
186
                        {
 
187
                        /* The plane color: */
 
188
                        scale_factor = (plane_delta_z +
 
189
                                        curr_planeSP->circle_radius) *
 
190
                                        reciprocal_diameter;
 
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)
 
194
                            {
 
195
                            plane_colorID = WeightColors_ (
 
196
                                        curr_planeSP->top_near_colorID,
 
197
                                        curr_planeSP->top_far_colorID,
 
198
                                        scale_factor, guiSP);
 
199
                            }
 
200
                        else
 
201
                            {
 
202
                            plane_colorID = WeightColors_ (
 
203
                                        curr_planeSP->bottom_near_colorID,
 
204
                                        curr_planeSP->bottom_far_colorID,
 
205
                                        scale_factor, guiSP);
 
206
                            }
 
207
 
 
208
                        /* The color of the object which was */
 
209
                        /* drawn  before  the current plane: */
 
210
                        old_colorID = curr_pixelSP->colorID;
 
211
 
 
212
                        /* The weighting factor which should be used */
 
213
                        /* to mix the plane color and the old color: */
 
214
                        scale_factor = curr_planeSP->transparency;
 
215
 
 
216
                        /* Mix the plane color and the old color: */
 
217
                        colorID = WeightColors_ (plane_colorID,
 
218
                                                 old_colorID,
 
219
                                                 scale_factor, guiSP);
 
220
                        }
 
221
                    }
 
222
 
 
223
                /* If nothing was drawn to the current pixel */
 
224
                /* in this drawing step,  prepare the color: */
 
225
                else
 
226
                    {
 
227
                    /* Prepare the scale factor used to weight (mix) colors: */
 
228
                    scale_factor = (plane_delta_z +
 
229
                                    curr_planeSP->circle_radius) *
 
230
                                    reciprocal_diameter;
 
231
                    if (scale_factor < 0.0) scale_factor = 0.0;
 
232
                    if (scale_factor > 1.0) scale_factor = 1.0;
 
233
 
 
234
                    /* Prepare the color by weighting */
 
235
                    /* (mixing)  near and  far color: */
 
236
                    if (curr_planeSP->visible_sideI[imageI] == 0)
 
237
                        {
 
238
                        colorID = WeightColors_ (
 
239
                                        curr_planeSP->top_near_colorID,
 
240
                                        curr_planeSP->top_far_colorID,
 
241
                                        scale_factor, guiSP);
 
242
                        }
 
243
                    else
 
244
                        {
 
245
                        colorID = WeightColors_ (
 
246
                                        curr_planeSP->bottom_near_colorID,
 
247
                                        curr_planeSP->bottom_far_colorID,
 
248
                                        scale_factor, guiSP);
 
249
                        }
 
250
 
 
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;
 
254
                    }
 
255
 
 
256
                /* Draw point: */
 
257
                XSetForeground (guiSP->displaySP, guiSP->theGCA[0], colorID);
 
258
                XDrawPoint (guiSP->displaySP, guiSP->main_hidden_pixmapID,
 
259
                            guiSP->theGCA[0], screen_x, screen_y);
 
260
 
 
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;
 
266
                }
 
267
            }
 
268
        }
 
269
    }
 
270
 
 
271
/* Return positive value (trivial): */
 
272
return 1;
 
273
}
 
274
 
 
275
/*===========================================================================*/
 
276
 
 
277