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

« back to all changes in this revision

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