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