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 planar (linear) in this function. Two planes,
10
perpendicular to z axis, define the area of color fading. All atoms
11
closer to the observer than the front plane will have the near atom
12
color. All atoms behind the back surface will have the far atom
13
color. RGB values are calculated from basic colors for each atom in
14
the area between two planes. XAllocColor is not used, because it may
18
(1) Pointer to MolComplexS structure.
19
(2) Pointer to GUIS structure.
22
(1) left_colorID, middle_colorID and right_colorID members of AtomS
23
structure initialized for each atom in macromolecular complex.
27
(1) On success, the number of atoms which have colors different from
28
near and far color. These atoms are located in the area between
29
the front and back surface.
33
(1) Do not skip hidden atoms, the color of these atoms may be used
36
=============================================================================*/
42
#include <X11/Xutil.h>
44
#include <X11/Xatom.h>
49
/*======function prototypes:=================================================*/
51
unsigned long PixelFromRGBS_ (RGBS *, GUIS *);
52
unsigned long PrepareColor_ (RGBS *, RGBS *, double, GUIS *);
54
/*======planar fading:=======================================================*/
56
size_t PlanarFading_ (MolComplexS *curr_mol_complexSP, GUIS *guiSP)
58
size_t atoms_between_surfacesN = 0;
61
int surfacesN, surfaceI, near_surfaceI, far_surfaceI;
63
double overall_range, internal_range;
64
double inverse_internal_range;
65
double delta_z, scale_factor;
67
/* The number of atoms in a complex: */
68
atomsN = curr_mol_complexSP->atomsN;
70
/* The z coordinate of the front surface (plane): */
71
z0 = curr_mol_complexSP->fading_front_relative_position +
72
curr_mol_complexSP->fading_center_vectorS.z;
74
/* The z coordinate of the back surface (plane): */
75
z1 = curr_mol_complexSP->fading_back_relative_position +
76
curr_mol_complexSP->fading_center_vectorS.z;
79
if (z0 >= z1) return 0;
81
/* The overall range: */
82
overall_range = z1 - z0;
84
/* Assign three colors to each atom: */
85
for (atomI = 0; atomI < atomsN; atomI++)
87
/** Pointer to the current atom: **/
88
curr_atomSP = curr_mol_complexSP->atomSP + atomI;
90
/** Is atom out of slab? **/
91
if (!curr_atomSP->inside_slabF) continue;
93
/** Check the number of color fading surfaces: **/
94
surfacesN = curr_atomSP->surfacesN;
95
/*** If there is only one, there is no fading: ***/
98
curr_atomSP->left_colorID =
99
PixelFromRGBS_ (curr_atomSP->left_rgbSA, guiSP);
100
curr_atomSP->middle_colorID =
101
PixelFromRGBS_ (curr_atomSP->middle_rgbSA, guiSP);
102
curr_atomSP->right_colorID =
103
PixelFromRGBS_ (curr_atomSP->right_rgbSA, guiSP);
107
/** The z coordinate of the current atom: **/
108
z = curr_atomSP->raw_atomS.z[0];
110
/** If current atom is closer to the observer than **/
111
/** the front surface, near colors should be used: **/
114
curr_atomSP->left_colorID =
115
PixelFromRGBS_ (curr_atomSP->left_rgbSA, guiSP);
116
curr_atomSP->middle_colorID =
117
PixelFromRGBS_ (curr_atomSP->middle_rgbSA, guiSP);
118
curr_atomSP->right_colorID =
119
PixelFromRGBS_ (curr_atomSP->right_rgbSA, guiSP);
123
/** If current atom is behind the back **/
124
/** surface, far colors should be used: **/
127
surfaceI = surfacesN - 1;
128
curr_atomSP->left_colorID =
129
PixelFromRGBS_ (curr_atomSP->left_rgbSA + surfaceI,
131
curr_atomSP->middle_colorID =
132
PixelFromRGBS_ (curr_atomSP->middle_rgbSA + surfaceI,
134
curr_atomSP->right_colorID =
135
PixelFromRGBS_ (curr_atomSP->right_rgbSA + surfaceI,
140
/** If this point is reached, current atom is in **/
141
/** the area between two surfaces; colors should **/
142
/** be calculated weighting near and far colors: **/
144
/** Prepare auxiliary variables: **/
147
internal_range = overall_range / (double) (surfacesN - 1);
148
inverse_internal_range = 1.0 / internal_range;
149
near_surfaceI = (int) floor ((z - z0) *
150
inverse_internal_range);
151
far_surfaceI = near_surfaceI + 1;
152
delta_z = z - near_surfaceI * internal_range - z0;
153
scale_factor = delta_z * inverse_internal_range;
163
curr_atomSP->left_colorID =
164
PrepareColor_ (curr_atomSP->left_rgbSA + near_surfaceI,
165
curr_atomSP->left_rgbSA + far_surfaceI,
166
scale_factor, guiSP);
168
/** Middle color: **/
169
curr_atomSP->middle_colorID =
170
PrepareColor_ (curr_atomSP->middle_rgbSA + near_surfaceI,
171
curr_atomSP->middle_rgbSA + far_surfaceI,
172
scale_factor, guiSP);
175
curr_atomSP->right_colorID =
176
PrepareColor_ (curr_atomSP->right_rgbSA + near_surfaceI,
177
curr_atomSP->right_rgbSA + far_surfaceI,
178
scale_factor, guiSP);
180
/** Update the number of atoms in the area between two surfaces: **/
181
atoms_between_surfacesN++;
184
/* Return the number of atoms which have */
185
/* colors different from near and far colors: */
186
return atoms_between_surfacesN;
189
/*===========================================================================*/