1
/* Copyright (C) 2000 Damir Zucic */
3
/*=============================================================================
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
14
(1) Pointer to MolComplexS structure.
15
(2) Pointer to GUIS structure.
18
(1) left_colorID, middle_colorID and right_colorID members of AtomS
19
structure initialized for each atom in macromolecular complex.
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.
29
(1) Do not skip hidden atoms, the color of these atoms may be used
32
=============================================================================*/
38
#include <X11/Xutil.h>
40
#include <X11/Xatom.h>
45
/*======function prototypes:=================================================*/
47
unsigned long PixelFromRGBS_ (RGBS *, GUIS *);
48
unsigned long PrepareColor_ (RGBS *, RGBS *, double, GUIS *);
50
/*======semi-cylindrical fading:=============================================*/
52
size_t HalfCylinFading_ (MolComplexS *curr_mol_complexSP, GUIS *guiSP)
54
size_t atoms_between_surfacesN = 0;
57
int surfacesN, surfaceI, inner_surfaceI, outer_surfaceI;
58
double rho_out, rho_out_squared, rho_in, rho_in_squared;
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;
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;
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;
74
if (rho_in >= rho_out) return 0;
76
/* The overall range: */
77
overall_range = rho_out - rho_in;
79
/* Fading center coordinates: */
80
x0 = curr_mol_complexSP->fading_center_vectorS.x;
81
z0 = curr_mol_complexSP->fading_center_vectorS.z;
83
/* The number of atoms in a complex: */
84
atomsN = curr_mol_complexSP->atomsN;
86
/* Assign three colors to each atom: */
87
for (atomI = 0; atomI < atomsN; atomI++)
89
/** Pointer to the current atom: **/
90
curr_atomSP = curr_mol_complexSP->atomSP + atomI;
92
/** Is atom out of slab? **/
93
if (!curr_atomSP->inside_slabF) continue;
95
/** Check the number of color fading surfaces: **/
96
surfacesN = curr_atomSP->surfacesN;
97
/*** If there is only one, there is no fading: ***/
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);
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;
113
/** Check is atom behind the plane; if it is, treat it as far atom: **/
116
surfaceI = surfacesN - 1;
117
curr_atomSP->left_colorID =
118
PixelFromRGBS_ (curr_atomSP->left_rgbSA + surfaceI,
120
curr_atomSP->middle_colorID =
121
PixelFromRGBS_ (curr_atomSP->middle_rgbSA + surfaceI,
123
curr_atomSP->right_colorID =
124
PixelFromRGBS_ (curr_atomSP->right_rgbSA + surfaceI,
129
/** Distance between the current atom and the fading axis: **/
130
rho_squared = x * x + z * z;
132
/** Atoms which are too far from the fading **/
133
/** axis should be treated as near atoms: **/
134
if (rho_squared >= rho_out_squared)
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);
145
/** Atoms which are to close to the fading **/
146
/** axis should be treated as far atoms: **/
147
if (rho_squared <= rho_in_squared)
149
surfaceI = surfacesN - 1;
150
curr_atomSP->left_colorID =
151
PixelFromRGBS_ (curr_atomSP->left_rgbSA + surfaceI,
153
curr_atomSP->middle_colorID =
154
PixelFromRGBS_ (curr_atomSP->middle_rgbSA + surfaceI,
156
curr_atomSP->right_colorID =
157
PixelFromRGBS_ (curr_atomSP->right_rgbSA + surfaceI,
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: **/
166
/** Prepare auxiliary variables: **/
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;
188
curr_atomSP->left_colorID =
189
PrepareColor_ (curr_atomSP->left_rgbSA + near_surfaceI,
190
curr_atomSP->left_rgbSA + far_surfaceI,
191
scale_factor, guiSP);
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);
200
curr_atomSP->right_colorID =
201
PrepareColor_ (curr_atomSP->right_rgbSA + near_surfaceI,
202
curr_atomSP->right_rgbSA + far_surfaceI,
203
scale_factor, guiSP);
205
/** Update the number of atoms in the area between two surfaces: **/
206
atoms_between_surfacesN++;
209
/* Return the number of atoms which have */
210
/* colors different from near and far colors: */
211
return atoms_between_surfacesN;
214
/*===========================================================================*/