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

« back to all changes in this revision

Viewing changes to big_spheres.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
                                big_spheres.c
 
6
 
 
7
Purpose:
 
8
        Draw atoms as big spheres.
 
9
 
 
10
Input:
 
11
        (1) Pointer to MolComplexS structure.
 
12
        (2) Number of macromolecular complexes.
 
13
        (3) Pointer to ConfigS structure, with configuration data.
 
14
        (4) Pointer to GUIS structure.
 
15
        (5) Pointer to NearestAtomS structure, with information about the
 
16
            atom occupying the given pixel.
 
17
        (6) The number of pixels in the main window free area.
 
18
        (7) The refreshI, used to check the  NearestAtomS associated with
 
19
            a given pixel.
 
20
 
 
21
Output:
 
22
        (1) Spheres drawn to the hidden pixmap.
 
23
        (2) Return value.
 
24
 
 
25
Return value:
 
26
        (1) Positive always (trivial).
 
27
 
 
28
Notes:
 
29
        (1) Indentation is exceptionally 4 spaces.
 
30
 
 
31
        (2) The atomic radii used in this function are based on the radii
 
32
            used in spacefill drawing function (spacefill.c).  The values
 
33
            used here are 50% larger.
 
34
 
 
35
=============================================================================*/
 
36
 
 
37
#include <stdio.h>
 
38
 
 
39
#include <math.h>
 
40
 
 
41
#include <X11/Xlib.h>
 
42
#include <X11/Xutil.h>
 
43
#include <X11/Xos.h>
 
44
#include <X11/Xatom.h>
 
45
 
 
46
#include "defines.h"
 
47
#include "typedefs.h"
 
48
 
 
49
/*======function prototypes:=================================================*/
 
50
 
 
51
unsigned long   SpacefillColor_ (AtomS *, GUIS *, double);
 
52
 
 
53
/*======draw atoms as big spheres:===========================================*/
 
54
 
 
55
int DrawBigSpheres_ (MolComplexS *mol_complexSP, int mol_complexesN,
 
56
                     ConfigS *configSP, GUIS *guiSP,
 
57
                     NearestAtomS *nearest_atomSP, size_t pixelsN,
 
58
                     unsigned int refreshI)
 
59
{
 
60
int                     imageI, imagesN;
 
61
double                  scale_factor, user_atomic_position;
 
62
int                     left_edge[2], right_edge[2];
 
63
int                     mol_complexI;
 
64
MolComplexS             *curr_mol_complexSP;
 
65
size_t                  atomsN, atomI;
 
66
AtomS                   *curr_atomSP;
 
67
int                     screen_x0, screen_y0;
 
68
double                  radius, radius_squared;
 
69
double                  denominator, reciprocal_denominator;
 
70
int                     screen_radius;
 
71
long                    screen_radius_squared;
 
72
int                     screen_x1, screen_y1, screen_x2, screen_y2;
 
73
int                     screen_x, screen_y;
 
74
long                    delta_x, delta_y, distance_squared;
 
75
double                  z0, front_z, delta_z, z;
 
76
size_t                  pixelI;
 
77
NearestAtomS            *curr_pixelSP;
 
78
double                  denominator2, reciprocal_denominator2;
 
79
double                  rho_squared;
 
80
VectorS                 vectorS;
 
81
double                  abs_value, abs_value_squared;
 
82
double                  scalar_product, cos_angle;
 
83
unsigned long           colorID;
 
84
 
 
85
/* Number of images: */
 
86
if (configSP->stereoF) imagesN = 2;
 
87
else imagesN = 1;
 
88
 
 
89
scale_factor = configSP->user_screen_atomic_distance *
 
90
               configSP->atomic_to_screen_scale_x;
 
91
 
 
92
/* Prepare the user position in atomic coordinates: */
 
93
user_atomic_position = configSP->user_atomic_position;
 
94
 
 
95
/* Left and right image edge (in stereo mode there are two images): */
 
96
left_edge[0]  = configSP->image_screen_x0[0];
 
97
right_edge[0] = configSP->image_screen_x1[0];
 
98
left_edge[1]  = configSP->image_screen_x0[1];
 
99
right_edge[1] = configSP->image_screen_x1[1];
 
100
 
 
101
/*------first pass - fill NearestAtomS array with planar atoms:--------------*/
 
102
 
 
103
/* Draw each macromolecular complex: */
 
104
for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
 
105
    {
 
106
    /* Pointer to current macromolecular complex: */
 
107
    curr_mol_complexSP = mol_complexSP + mol_complexI;
 
108
 
 
109
    /* Prepare and check the number of atoms: */
 
110
    atomsN = curr_mol_complexSP->atomsN;
 
111
    if (atomsN == 0) continue;
 
112
 
 
113
    /* Draw atoms which have the given style: */
 
114
    for (atomI = 0; atomI < atomsN; atomI++)
 
115
        {
 
116
        /* Pointer to the current atom: */
 
117
        curr_atomSP = curr_mol_complexSP->atomSP + atomI;
 
118
 
 
119
        /* Check style: */
 
120
        if (curr_atomSP->raw_atomS.atom_styleI != BIG_SPHERE) continue;
 
121
 
 
122
        /* Check is atom hidden: */
 
123
        if (curr_atomSP->hiddenF) continue;
 
124
 
 
125
        /* Check is atom inside slab: */
 
126
        if (!curr_atomSP->inside_slabF) continue;
 
127
 
 
128
        /* Check is atom inside window: */
 
129
        if (!curr_atomSP->inside_windowF) continue;
 
130
 
 
131
        /* Atomic radius, in atomic units: */
 
132
        radius = curr_atomSP->raw_atomS.van_der_Waals_radius;
 
133
 
 
134
        /* Squared atomic radius: */
 
135
        radius_squared = radius * radius;
 
136
 
 
137
        /* The y coordinate of atomic center, in screen units: */
 
138
        screen_y0 = curr_atomSP->raw_atomS.screen_y;
 
139
 
 
140
        /* Prepare one image (mono) or two images (stereo): */
 
141
        for (imageI = 0; imageI < imagesN; imageI++)
 
142
            {
 
143
            /* The z coordinate of atomic center, in atomic units: */
 
144
            z0 = curr_atomSP->raw_atomS.z[imageI];
 
145
 
 
146
            /* Prepare the factor required for projection of atomic radius: */
 
147
            denominator = z0 - user_atomic_position;
 
148
            if (denominator == 0.0) continue;
 
149
            reciprocal_denominator = 1.0 / denominator;
 
150
 
 
151
            /* Atomic radius in screen units: */
 
152
            screen_radius = (int) (radius *
 
153
                                   scale_factor *
 
154
                                   reciprocal_denominator +
 
155
                                   0.5);
 
156
 
 
157
            /* Screen radius squared (used to improve speed): */
 
158
            screen_radius_squared = (long) screen_radius *
 
159
                                    (long) screen_radius;
 
160
 
 
161
            /* The x coordinate of atomic center, in screen units: */
 
162
            screen_x0 = curr_atomSP->raw_atomS.screen_x[imageI];
 
163
 
 
164
            /* Define the bounding rectangle: */
 
165
            screen_x1 = screen_x0 - screen_radius;
 
166
            screen_y1 = screen_y0 - screen_radius;
 
167
            screen_x2 = screen_x0 + screen_radius;
 
168
            screen_y2 = screen_y0 + screen_radius;
 
169
 
 
170
            /* Horizontal scan: */
 
171
            for (screen_x = screen_x1; screen_x <= screen_x2; screen_x++)
 
172
                {
 
173
                /* Check horizontal position: */
 
174
                if (screen_x < left_edge[imageI])  continue;
 
175
                if (screen_x > right_edge[imageI]) continue;
 
176
 
 
177
                /* Vertical scan: */
 
178
                for (screen_y = screen_y1; screen_y <= screen_y2; screen_y++)
 
179
                    {
 
180
                    /* Check vertical position: */
 
181
                    if (screen_y < 0) continue;
 
182
                    if (screen_y >= guiSP->main_win_free_area_height) continue;
 
183
 
 
184
                    /* Check distance from the circle center: */
 
185
                    delta_x = (long) (screen_x - screen_x0);
 
186
                    delta_y = (long) (screen_y - screen_y0);
 
187
                    distance_squared = delta_x * delta_x + delta_y * delta_y;
 
188
                    if (distance_squared > screen_radius_squared) continue;
 
189
 
 
190
                    /* Prepare index  to the array */
 
191
                    /* of NearestAtomS structures: */
 
192
                    pixelI = guiSP->main_win_free_area_width * screen_y +
 
193
                             screen_x;
 
194
 
 
195
                    /* Check the pixel index: */
 
196
                    if (pixelI >= pixelsN) continue;
 
197
 
 
198
                    /* Pointer to  NearestAtomS struct. */
 
199
                    /* assigned to current coordinates: */
 
200
                    curr_pixelSP = nearest_atomSP + pixelI;
 
201
 
 
202
                    /* Check was  this pixel used  already in */
 
203
                    /* this drawing step;  if it was, compare */
 
204
                    /* the z value of the current atom with z */
 
205
                    /* value previously stored to this pixel: */
 
206
                    if (refreshI == curr_pixelSP->last_refreshI)
 
207
                        {
 
208
                        if (z0 > curr_pixelSP->z) continue;
 
209
                        }
 
210
 
 
211
                    /* Refresh the content of NearestAtomS */
 
212
                    /* array  associated  with this pixel: */
 
213
                    curr_pixelSP->styleI = BIG_SPHERE;
 
214
                    curr_pixelSP->last_refreshI = refreshI;
 
215
                    curr_pixelSP->mol_complexI = mol_complexI;
 
216
                    curr_pixelSP->atomI = atomI;
 
217
                    curr_pixelSP->z = z0;
 
218
                    }
 
219
                }
 
220
        
 
221
            }   /* imageI loop */
 
222
        }       /* atomI  loop */
 
223
    }           /* mol_complexI loop */
 
224
 
 
225
/*------second pass - draw spherical atoms:----------------------------------*/
 
226
 
 
227
/* Draw each macromolecular complex: */
 
228
for (mol_complexI = 0; mol_complexI < mol_complexesN; mol_complexI++)
 
229
    {
 
230
    /* Pointer to current macromolecular complex: */
 
231
    curr_mol_complexSP = mol_complexSP + mol_complexI;
 
232
 
 
233
    /* Prepare and check the number of atoms: */
 
234
    atomsN = curr_mol_complexSP->atomsN;
 
235
    if (atomsN == 0) continue;
 
236
 
 
237
    /* Draw atoms which have the given style: */
 
238
    for (atomI = 0; atomI < atomsN; atomI++)
 
239
        {
 
240
        /* Pointer to the current atom: */
 
241
        curr_atomSP = curr_mol_complexSP->atomSP + atomI;
 
242
 
 
243
        /* Check style: */
 
244
        if (curr_atomSP->raw_atomS.atom_styleI != BIG_SPHERE) continue;
 
245
 
 
246
        /* Check is atom hidden: */
 
247
        if (curr_atomSP->hiddenF) continue;
 
248
 
 
249
        /* Check is atom inside slab: */
 
250
        if (!curr_atomSP->inside_slabF) continue;
 
251
 
 
252
        /* Check is atom inside window: */
 
253
        if (!curr_atomSP->inside_windowF) continue;
 
254
 
 
255
        /* Atomic radius, in atomic units: */
 
256
        radius = curr_atomSP->raw_atomS.van_der_Waals_radius;
 
257
 
 
258
        /* Squared atomic radius: */
 
259
        radius_squared = radius * radius;
 
260
 
 
261
        /* The y coordinate of atomic center, in screen units: */
 
262
        screen_y0 = curr_atomSP->raw_atomS.screen_y;
 
263
 
 
264
        /* Prepare one image (mono) or two images (stereo): */
 
265
        for (imageI = 0; imageI < imagesN; imageI++)
 
266
            {
 
267
            /* The z coordinate of atomic center, in atomic units: */
 
268
            z0 = curr_atomSP->raw_atomS.z[imageI];
 
269
 
 
270
            /* The z coordinate of the nearest */
 
271
            /* point of a given atom (sphere): */
 
272
            front_z = z0 - radius;
 
273
 
 
274
            /* Prepare the factor required for projection of atomic radius: */
 
275
            denominator = z0 - user_atomic_position;
 
276
            if (denominator == 0.0) continue;
 
277
            reciprocal_denominator = 1.0 / denominator;
 
278
 
 
279
            /* Atomic radius in screen units: */
 
280
            screen_radius = (int) (radius *
 
281
                                   scale_factor *
 
282
                                   reciprocal_denominator +
 
283
                                   0.5);
 
284
 
 
285
            /* Square of the atomic radius (in screen units): */
 
286
            screen_radius_squared = (long) screen_radius *
 
287
                                    (long) screen_radius;
 
288
 
 
289
            /* Reciprocal value will be used to improve performance: */
 
290
            denominator2 = (double) screen_radius_squared;
 
291
            if (denominator2 == 0.0) continue;
 
292
            reciprocal_denominator2 = 1.0 / denominator2;
 
293
 
 
294
            /* The x coordinate of atomic center, in screen units: */
 
295
            screen_x0 = curr_atomSP->raw_atomS.screen_x[imageI];
 
296
 
 
297
            /* Define the bounding rectangle: */
 
298
            screen_x1 = screen_x0 - screen_radius;
 
299
            screen_y1 = screen_y0 - screen_radius;
 
300
            screen_x2 = screen_x0 + screen_radius;
 
301
            screen_y2 = screen_y0 + screen_radius;
 
302
 
 
303
            /* Horizontal scan: */
 
304
            for (screen_x = screen_x1; screen_x <= screen_x2; screen_x++)
 
305
                {
 
306
                /* Check horizontal position: */
 
307
                if (screen_x < left_edge[imageI])  continue;
 
308
                if (screen_x > right_edge[imageI]) continue;
 
309
 
 
310
                /* Vertical scan: */
 
311
                for (screen_y = screen_y1; screen_y <= screen_y2; screen_y++)
 
312
                    {
 
313
                    /* Check vertical position: */
 
314
                    if (screen_y < 0) continue;
 
315
                    if (screen_y >= guiSP->main_win_free_area_height) continue;
 
316
 
 
317
                    /* Check distance from the circle center: */
 
318
                    delta_x = (long) (screen_x - screen_x0);
 
319
                    delta_y = (long) (screen_y - screen_y0);
 
320
                    distance_squared = delta_x * delta_x + delta_y * delta_y;
 
321
                    if (distance_squared > screen_radius_squared) continue;
 
322
 
 
323
                    /* Prepare index  to the array */
 
324
                    /* of NearestAtomS structures: */
 
325
                    pixelI = guiSP->main_win_free_area_width * screen_y +
 
326
                             screen_x;
 
327
 
 
328
                    /* Check the pixel index: */
 
329
                    if (pixelI >= pixelsN) continue;
 
330
 
 
331
                    /* Pointer to  NearestAtomS struct. */
 
332
                    /* assigned to current coordinates: */
 
333
                    curr_pixelSP = nearest_atomSP + pixelI;
 
334
 
 
335
                    /* Check z value (this is just a quick check): */
 
336
                    if (refreshI == curr_pixelSP->last_refreshI)
 
337
                        {
 
338
                        if (front_z > curr_pixelSP->z) continue;
 
339
                        }
 
340
 
 
341
                    /* Calculate the accurate z value: */
 
342
                    rho_squared = radius_squared *
 
343
                                  (double) distance_squared *
 
344
                                  reciprocal_denominator2;
 
345
                    delta_z = sqrt (fabs (radius_squared - rho_squared));
 
346
                    z = z0 - delta_z;
 
347
 
 
348
                    /* Check z value (precise check): */
 
349
                    if (refreshI == curr_pixelSP->last_refreshI)
 
350
                        {
 
351
                        if (z > curr_pixelSP->z) continue;
 
352
                        }
 
353
 
 
354
                    /* The vector from sphere center to the current pixel: */
 
355
                    vectorS.x = (double) delta_x;
 
356
                    vectorS.y = (double) delta_y;
 
357
                    vectorS.z = -delta_z * scale_factor *
 
358
                                reciprocal_denominator;
 
359
                    abs_value_squared = vectorS.x * vectorS.x +
 
360
                                        vectorS.y * vectorS.y +
 
361
                                        vectorS.z * vectorS.z;
 
362
                    abs_value = sqrt (abs_value_squared);
 
363
 
 
364
                    /* The scalar product  between this */
 
365
                    /* vector and  light source vector: */
 
366
                    scalar_product = vectorS.x * configSP->light_vectorS.x +
 
367
                                     vectorS.y * configSP->light_vectorS.y +
 
368
                                     vectorS.z * configSP->light_vectorS.z;
 
369
 
 
370
                    /* Cosine of  the angle between  the vector to the */
 
371
                    /* current pixel and the light source unit vector: */
 
372
                    if (abs_value == 0.0) cos_angle = 0.0;
 
373
                    else cos_angle = scalar_product / abs_value;
 
374
 
 
375
                    /* Prepare color: */
 
376
                    colorID = SpacefillColor_ (curr_atomSP, guiSP, cos_angle);
 
377
 
 
378
                    XSetForeground (guiSP->displaySP,
 
379
                                    guiSP->theGCA[0],
 
380
                                    colorID);
 
381
 
 
382
                    XDrawPoint (guiSP->displaySP,
 
383
                                guiSP->main_hidden_pixmapID,
 
384
                                guiSP->theGCA[0],
 
385
                                screen_x, screen_y);
 
386
 
 
387
                    /* Refresh the content of NearestAtomS */
 
388
                    /* array  associated  with this pixel: */
 
389
                    curr_pixelSP->styleI = BIG_SPHERE;
 
390
                    curr_pixelSP->last_refreshI = refreshI;
 
391
                    curr_pixelSP->mol_complexI = mol_complexI;
 
392
                    curr_pixelSP->atomI = atomI;
 
393
                    curr_pixelSP->z = z;
 
394
                    curr_pixelSP->colorID = colorID;
 
395
                    }
 
396
                }
 
397
        
 
398
            }   /* imageI loop */
 
399
        }       /* atomI  loop */
 
400
    }           /* mol_complexI loop */
 
401
 
 
402
/*---------------------------------------------------------------------------*/
 
403
 
 
404
/* Return positive value (trivial): */
 
405
return 1;
 
406
}
 
407
 
 
408
/*===========================================================================*/
 
409
 
 
410