1 /* Copyright (C) 2000-2002 Damir Zucic */
2
3 /*=============================================================================
4
5 sp2_color.c
6
7 Purpose:
8 Prepare spacefill color, version 2. In this function white, left,
9 middle, right and black color are used.
10
11 Input:
12 (1) Pointer to AtomS structure.
13 (2) Pointer to GUIS structure.
14 (3) Cosine of the angle between the vector from sphere center and
15 the current pixel and the light source unit vector. It will
16 be used to calculate the angle.
17
18 Output:
19 (1) Return value.
20
21 Return value:
22 The pixel (color) value.
23
24 Notes:
25 (1) This function may be quite slow (a lot of math).
26
27 =============================================================================*/
28
29 #include <stdio.h>
30
31 #include <math.h>
32
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
35 #include <X11/Xos.h>
36 #include <X11/Xatom.h>
37
38 #include "defines.h"
39 #include "typedefs.h"
40
41 /*======spacefill color:=====================================================*/
42
Sp2Color_(AtomS * curr_atomSP,GUIS * guiSP,double cos_angle)43 unsigned long Sp2Color_ (AtomS *curr_atomSP, GUIS *guiSP, double cos_angle)
44 {
45 static long double angle;
46 static long double angle1 = 10.0, angle2 = 40.0;
47 static long double angle3 = 80.0, angle4 = 130.0;
48 static long double delta_angle;
49 static long double w0 = 0.100000, w1 = 0.033333;
50 static long double w2 = 0.025000, w3 = 0.020000;
51 static unsigned long colorID;
52 static unsigned long red_mask, green_mask, blue_mask;
53 static unsigned long red1, red2, red;
54 static unsigned long green1, green2, green;
55 static unsigned long blue1, blue2, blue;
56 static long double r1, r2, g1, g2, b1, b2;
57 static long double r, g, b;
58
59 /* Calculate the angle, in degrees: */
60 if (cos_angle <= -1.0) angle = 180.0;
61 else if (cos_angle >= 1.0) angle = 0.0;
62 else angle = RAD_TO_DEG * acos (cos_angle);
63
64 /* Copy masks: */
65 red_mask = guiSP->visual_infoS.red_mask;
66 green_mask = guiSP->visual_infoS.green_mask;
67 blue_mask = guiSP->visual_infoS.blue_mask;
68
69 /* Find sector and prepare color components: */
70 if (angle >= angle4)
71 {
72 return (guiSP->black_colorID);
73 }
74
75 else if (angle >= angle3)
76 {
77 /* Extract input color components: */
78 red1 = curr_atomSP->right_colorID & red_mask;
79 red2 = guiSP->black_colorID & red_mask;
80 green1 = curr_atomSP->right_colorID & green_mask;
81 green2 = guiSP->black_colorID & green_mask;
82 blue1 = curr_atomSP->right_colorID & blue_mask;
83 blue2 = guiSP->black_colorID & blue_mask;
84
85 /* Convert to doubles: */
86 r1 = (long double) red1;
87 r2 = (long double) red2;
88 g1 = (long double) green1;
89 g2 = (long double) green2;
90 b1 = (long double) blue1;
91 b2 = (long double) blue2;
92
93 /* Calculate new color components: */
94 delta_angle = angle - angle3;
95 r = r1 + w3 * (r2 - r1) * delta_angle;
96 g = g1 + w3 * (g2 - g1) * delta_angle;
97 b = b1 + w3 * (b2 - b1) * delta_angle;
98 }
99
100 else if (angle >= angle2)
101 {
102 /* Extract input color components: */
103 red1 = curr_atomSP->middle_colorID & red_mask;
104 red2 = curr_atomSP->right_colorID & red_mask;
105 green1 = curr_atomSP->middle_colorID & green_mask;
106 green2 = curr_atomSP->right_colorID & green_mask;
107 blue1 = curr_atomSP->middle_colorID & blue_mask;
108 blue2 = curr_atomSP->right_colorID & blue_mask;
109
110 /* Convert to doubles: */
111 r1 = (long double) red1;
112 r2 = (long double) red2;
113 g1 = (long double) green1;
114 g2 = (long double) green2;
115 b1 = (long double) blue1;
116 b2 = (long double) blue2;
117
118 /* Calculate new color components: */
119 delta_angle = angle - angle2;
120 r = r1 + w2 * (r2 - r1) * delta_angle;
121 g = g1 + w2 * (g2 - g1) * delta_angle;
122 b = b1 + w2 * (b2 - b1) * delta_angle;
123 }
124
125 else if (angle >= angle1)
126 {
127 /* Extract input color components: */
128 red1 = curr_atomSP->left_colorID & red_mask;
129 red2 = curr_atomSP->middle_colorID & red_mask;
130 green1 = curr_atomSP->left_colorID & green_mask;
131 green2 = curr_atomSP->middle_colorID & green_mask;
132 blue1 = curr_atomSP->left_colorID & blue_mask;
133 blue2 = curr_atomSP->middle_colorID & blue_mask;
134
135 /* Convert to doubles: */
136 r1 = (long double) red1;
137 r2 = (long double) red2;
138 g1 = (long double) green1;
139 g2 = (long double) green2;
140 b1 = (long double) blue1;
141 b2 = (long double) blue2;
142
143 /* Calculate new color components: */
144 delta_angle = angle - angle1;
145 r = r1 + w1 * (r2 - r1) * delta_angle;
146 g = g1 + w1 * (g2 - g1) * delta_angle;
147 b = b1 + w1 * (b2 - b1) * delta_angle;
148 }
149
150 else
151 {
152 /* Extract input color components: */
153 red1 = guiSP->white_colorID & red_mask;
154 red2 = curr_atomSP->left_colorID & red_mask;
155 green1 = guiSP->white_colorID & green_mask;
156 green2 = curr_atomSP->left_colorID & green_mask;
157 blue1 = guiSP->white_colorID & blue_mask;
158 blue2 = curr_atomSP->left_colorID & blue_mask;
159
160 /* Convert to doubles: */
161 r1 = (long double) red1;
162 r2 = (long double) red2;
163 g1 = (long double) green1;
164 g2 = (long double) green2;
165 b1 = (long double) blue1;
166 b2 = (long double) blue2;
167
168 /* Calculate new color components: */
169 delta_angle = angle;
170 r = r1 + w0 * (r2 - r1) * delta_angle;
171 g = g1 + w0 * (g2 - g1) * delta_angle;
172 b = b1 + w0 * (b2 - b1) * delta_angle;
173 }
174
175 /* Check new color components: */
176 if (r < 0.0) r = 0.0;
177 if (g < 0.0) g = 0.0;
178 if (b < 0.0) b = 0.0;
179
180 /* Convert new color components: */
181 red = ((unsigned long) r) & red_mask;
182 green = ((unsigned long) g) & green_mask;
183 blue = ((unsigned long) b) & blue_mask;
184
185 /* Combine new color components: */
186 colorID = red | green | blue;
187
188 /* Return the pixel value: */
189 return colorID;
190 }
191
192 /*===========================================================================*/
193
194
195