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