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

« back to all changes in this revision

Viewing changes to half_cylin_fading.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
                                half_cylin_fading.c
 
6
 
 
7
Purpose:
 
8
        Prepare the left, middle and right color for each atom in a complex.
 
9
        The color fading is semi-cylindrical.  The cylinder axis is parallel
 
10
        to y axis.  The plane is parallel to x-y plane,  passing through the
 
11
        fading center.
 
12
 
 
13
Input:
 
14
        (1) Pointer to MolComplexS structure.
 
15
        (2) Pointer to GUIS structure.
 
16
 
 
17
Output:
 
18
        (1) left_colorID, middle_colorID and right_colorID members of  AtomS
 
19
            structure initialized for each atom in macromolecular complex.
 
20
        (2) Return value.
 
21
 
 
22
Return value:
 
23
        (1) On success, the number of atoms which have colors different from
 
24
            near and far color.  These atoms are located in the area between
 
25
            the front and back surface.
 
26
        (2) Zero on failure.
 
27
 
 
28
Notes:
 
29
        (1) Do not skip hidden atoms,  the color of these atoms  may be used
 
30
            for backbone drawing!
 
31
 
 
32
=============================================================================*/
 
33
 
 
34
#include <stdio.h>
 
35
#include <math.h>
 
36
 
 
37
#include <X11/Xlib.h>
 
38
#include <X11/Xutil.h>
 
39
#include <X11/Xos.h>
 
40
#include <X11/Xatom.h>
 
41
 
 
42
#include "defines.h"
 
43
#include "typedefs.h"
 
44
 
 
45
/*======function prototypes:=================================================*/
 
46
 
 
47
unsigned long   PixelFromRGBS_ (RGBS *, GUIS *);
 
48
unsigned long   PrepareColor_ (RGBS *, RGBS *, double, GUIS *);
 
49
 
 
50
/*======semi-cylindrical fading:=============================================*/
 
51
 
 
52
size_t HalfCylinFading_ (MolComplexS *curr_mol_complexSP, GUIS *guiSP)
 
53
{
 
54
size_t                  atoms_between_surfacesN = 0;
 
55
size_t                  atomsN, atomI;
 
56
AtomS                   *curr_atomSP;
 
57
int                     surfacesN, surfaceI, inner_surfaceI, outer_surfaceI;
 
58
double                  rho_out, rho_out_squared, rho_in, rho_in_squared;
 
59
double                  x0, z0;
 
60
double                  overall_range, internal_range;
 
61
double                  inverse_internal_range;
 
62
double                  x, z, rho_squared, rho, delta_rho, scale_factor;
 
63
int                     near_surfaceI, far_surfaceI;
 
64
 
 
65
/* The radius of the front (outer) surface: */
 
66
rho_out = curr_mol_complexSP->fading_front_relative_position;
 
67
rho_out_squared = rho_out * rho_out;
 
68
 
 
69
/* The radius of the back (inner) surface: */
 
70
rho_in = curr_mol_complexSP->fading_back_relative_position;
 
71
rho_in_squared = rho_in * rho_in;
 
72
 
 
73
/* Check: */
 
74
if (rho_in >= rho_out) return 0;
 
75
 
 
76
/* The overall range: */
 
77
overall_range = rho_out - rho_in;
 
78
 
 
79
/* Fading center coordinates: */
 
80
x0 = curr_mol_complexSP->fading_center_vectorS.x;
 
81
z0 = curr_mol_complexSP->fading_center_vectorS.z;
 
82
 
 
83
/* The number of atoms in a complex: */
 
84
atomsN = curr_mol_complexSP->atomsN;
 
85
 
 
86
/* Assign three colors to each atom: */
 
87
for (atomI = 0; atomI < atomsN; atomI++)
 
88
        {
 
89
        /** Pointer to the current atom: **/
 
90
        curr_atomSP = curr_mol_complexSP->atomSP + atomI;
 
91
 
 
92
        /** Is atom out of slab? **/
 
93
        if (!curr_atomSP->inside_slabF) continue;
 
94
 
 
95
        /** Check the number of color fading surfaces: **/
 
96
        surfacesN = curr_atomSP->surfacesN;
 
97
        /*** If there is only one, there is no fading: ***/
 
98
        if (surfacesN == 1)
 
99
                {
 
100
                curr_atomSP->left_colorID   =
 
101
                        PixelFromRGBS_ (curr_atomSP->left_rgbSA, guiSP);
 
102
                curr_atomSP->middle_colorID =
 
103
                        PixelFromRGBS_ (curr_atomSP->middle_rgbSA, guiSP);
 
104
                curr_atomSP->right_colorID  =
 
105
                        PixelFromRGBS_ (curr_atomSP->right_rgbSA, guiSP);
 
106
                continue;
 
107
                }
 
108
 
 
109
        /** Atomic coordinates (relative to the fading center): **/
 
110
        x = curr_atomSP->raw_atomS.x[0] - x0;
 
111
        z = curr_atomSP->raw_atomS.z[0] - z0;
 
112
 
 
113
        /** Check is atom behind the plane; if it is, treat it as far atom: **/
 
114
        if (z > 0.0)
 
115
                {
 
116
                surfaceI = surfacesN - 1;
 
117
                curr_atomSP->left_colorID   =
 
118
                        PixelFromRGBS_ (curr_atomSP->left_rgbSA + surfaceI,
 
119
                                        guiSP);
 
120
                curr_atomSP->middle_colorID =
 
121
                        PixelFromRGBS_ (curr_atomSP->middle_rgbSA + surfaceI,
 
122
                                        guiSP);
 
123
                curr_atomSP->right_colorID  =
 
124
                        PixelFromRGBS_ (curr_atomSP->right_rgbSA + surfaceI,
 
125
                                        guiSP);
 
126
                continue;
 
127
                }
 
128
 
 
129
        /** Distance between the current atom and the fading axis: **/
 
130
        rho_squared = x * x + z * z;
 
131
 
 
132
        /** Atoms which are too far from the fading **/
 
133
        /** axis should be  treated as  near atoms: **/
 
134
        if (rho_squared >= rho_out_squared)
 
135
                {
 
136
                curr_atomSP->left_colorID   =
 
137
                        PixelFromRGBS_ (curr_atomSP->left_rgbSA, guiSP);
 
138
                curr_atomSP->middle_colorID =
 
139
                        PixelFromRGBS_ (curr_atomSP->middle_rgbSA, guiSP);
 
140
                curr_atomSP->right_colorID  =
 
141
                        PixelFromRGBS_ (curr_atomSP->right_rgbSA, guiSP);
 
142
                continue;
 
143
                }
 
144
 
 
145
        /** Atoms which are to close to the fading **/
 
146
        /** axis should be  treated as  far atoms: **/
 
147
        if (rho_squared <= rho_in_squared)
 
148
                {
 
149
                surfaceI = surfacesN - 1;
 
150
                curr_atomSP->left_colorID   =
 
151
                        PixelFromRGBS_ (curr_atomSP->left_rgbSA + surfaceI,
 
152
                                        guiSP);
 
153
                curr_atomSP->middle_colorID =
 
154
                        PixelFromRGBS_ (curr_atomSP->middle_rgbSA + surfaceI,
 
155
                                        guiSP);
 
156
                curr_atomSP->right_colorID  =
 
157
                        PixelFromRGBS_ (curr_atomSP->right_rgbSA + surfaceI,
 
158
                                        guiSP);
 
159
                continue;
 
160
                }
 
161
 
 
162
        /** If this point is reached, current atom is in **/
 
163
        /** the area between two surfaces; colors should **/
 
164
        /** be calculated weighting near and far colors: **/
 
165
 
 
166
        /** Prepare auxiliary variables: **/
 
167
        if (surfacesN > 1)
 
168
                {
 
169
                rho = sqrt (rho_squared);
 
170
                internal_range = overall_range / (double) (surfacesN - 1);
 
171
                inverse_internal_range = 1.0 / internal_range;
 
172
                inner_surfaceI = (int) floor ((rho - rho_in) *
 
173
                                  inverse_internal_range);
 
174
                outer_surfaceI = inner_surfaceI + 1;
 
175
                delta_rho = outer_surfaceI * internal_range + rho_in - rho;
 
176
                scale_factor = delta_rho * inverse_internal_range;
 
177
                far_surfaceI = surfacesN - inner_surfaceI - 1;
 
178
                near_surfaceI = far_surfaceI - 1;
 
179
                }
 
180
        else
 
181
                {
 
182
                scale_factor = 0.0;
 
183
                far_surfaceI = 0;
 
184
                near_surfaceI = 0;
 
185
                }
 
186
 
 
187
        /** Left color: **/
 
188
        curr_atomSP->left_colorID =
 
189
                PrepareColor_ (curr_atomSP->left_rgbSA + near_surfaceI,
 
190
                               curr_atomSP->left_rgbSA + far_surfaceI,
 
191
                               scale_factor, guiSP);
 
192
 
 
193
        /** Middle color: **/
 
194
        curr_atomSP->middle_colorID =
 
195
                PrepareColor_ (curr_atomSP->middle_rgbSA + near_surfaceI,
 
196
                               curr_atomSP->middle_rgbSA + far_surfaceI,
 
197
                               scale_factor, guiSP);
 
198
 
 
199
        /** Right color: **/
 
200
        curr_atomSP->right_colorID =
 
201
                PrepareColor_ (curr_atomSP->right_rgbSA + near_surfaceI,
 
202
                               curr_atomSP->right_rgbSA + far_surfaceI,
 
203
                               scale_factor, guiSP);
 
204
 
 
205
        /** Update the number of atoms in the area between two surfaces: **/
 
206
        atoms_between_surfacesN++;
 
207
        }
 
208
 
 
209
/* Return  the  number  of atoms  which  have */
 
210
/* colors different from near and far colors: */
 
211
return atoms_between_surfacesN;
 
212
}
 
213
 
 
214
/*===========================================================================*/
 
215
 
 
216