xref: /inferno-os/libmemdraw/icossin2.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include	"lib9.h"
2 #include	"draw.h"
3 
4 /*
5  * Sine and Cosine of arctangents, calculated by
6  *   (sin(atan(index/100.0))*1024.+0.5)
7  *   (cos(atan(index/100.0))*1024.+0.5)
8  * To use, get rational tangent between 0<=tan<=1, scale by 100,
9  * and look up sin and cos, and use linear interpolation.  divide by 1024.
10  * Maximum error is 0.0020.  Without linear interpolation, it's 0.010.
11  */
12 static
13 short sinus[] = {
14 	0,	/* 0.00 */
15 	10,	/* 0.01 */
16 	20,	/* 0.02 */
17 	31,	/* 0.03 */
18 	41,	/* 0.04 */
19 	51,	/* 0.05 */
20 	61,	/* 0.06 */
21 	72,	/* 0.07 */
22 	82,	/* 0.08 */
23 	92,	/* 0.09 */
24 	102,	/* 0.10 */
25 	112,	/* 0.11 */
26 	122,	/* 0.12 */
27 	132,	/* 0.13 */
28 	142,	/* 0.14 */
29 	152,	/* 0.15 */
30 	162,	/* 0.16 */
31 	172,	/* 0.17 */
32 	181,	/* 0.18 */
33 	191,	/* 0.19 */
34 	201,	/* 0.20 */
35 	210,	/* 0.21 */
36 	220,	/* 0.22 */
37 	230,	/* 0.23 */
38 	239,	/* 0.24 */
39 	248,	/* 0.25 */
40 	258,	/* 0.26 */
41 	267,	/* 0.27 */
42 	276,	/* 0.28 */
43 	285,	/* 0.29 */
44 	294,	/* 0.30 */
45 	303,	/* 0.31 */
46 	312,	/* 0.32 */
47 	321,	/* 0.33 */
48 	330,	/* 0.34 */
49 	338,	/* 0.35 */
50 	347,	/* 0.36 */
51 	355,	/* 0.37 */
52 	364,	/* 0.38 */
53 	372,	/* 0.39 */
54 	380,	/* 0.40 */
55 	388,	/* 0.41 */
56 	397,	/* 0.42 */
57 	405,	/* 0.43 */
58 	412,	/* 0.44 */
59 	420,	/* 0.45 */
60 	428,	/* 0.46 */
61 	436,	/* 0.47 */
62 	443,	/* 0.48 */
63 	451,	/* 0.49 */
64 	458,	/* 0.50 */
65 	465,	/* 0.51 */
66 	472,	/* 0.52 */
67 	480,	/* 0.53 */
68 	487,	/* 0.54 */
69 	493,	/* 0.55 */
70 	500,	/* 0.56 */
71 	507,	/* 0.57 */
72 	514,	/* 0.58 */
73 	520,	/* 0.59 */
74 	527,	/* 0.60 */
75 	533,	/* 0.61 */
76 	540,	/* 0.62 */
77 	546,	/* 0.63 */
78 	552,	/* 0.64 */
79 	558,	/* 0.65 */
80 	564,	/* 0.66 */
81 	570,	/* 0.67 */
82 	576,	/* 0.68 */
83 	582,	/* 0.69 */
84 	587,	/* 0.70 */
85 	593,	/* 0.71 */
86 	598,	/* 0.72 */
87 	604,	/* 0.73 */
88 	609,	/* 0.74 */
89 	614,	/* 0.75 */
90 	620,	/* 0.76 */
91 	625,	/* 0.77 */
92 	630,	/* 0.78 */
93 	635,	/* 0.79 */
94 	640,	/* 0.80 */
95 	645,	/* 0.81 */
96 	649,	/* 0.82 */
97 	654,	/* 0.83 */
98 	659,	/* 0.84 */
99 	663,	/* 0.85 */
100 	668,	/* 0.86 */
101 	672,	/* 0.87 */
102 	676,	/* 0.88 */
103 	681,	/* 0.89 */
104 	685,	/* 0.90 */
105 	689,	/* 0.91 */
106 	693,	/* 0.92 */
107 	697,	/* 0.93 */
108 	701,	/* 0.94 */
109 	705,	/* 0.95 */
110 	709,	/* 0.96 */
111 	713,	/* 0.97 */
112 	717,	/* 0.98 */
113 	720,	/* 0.99 */
114 	724,	/* 1.00 */
115 	728,	/* 1.01 */
116 };
117 
118 static
119 short cosinus[] = {
120 	1024,	/* 0.00 */
121 	1024,	/* 0.01 */
122 	1024,	/* 0.02 */
123 	1024,	/* 0.03 */
124 	1023,	/* 0.04 */
125 	1023,	/* 0.05 */
126 	1022,	/* 0.06 */
127 	1022,	/* 0.07 */
128 	1021,	/* 0.08 */
129 	1020,	/* 0.09 */
130 	1019,	/* 0.10 */
131 	1018,	/* 0.11 */
132 	1017,	/* 0.12 */
133 	1015,	/* 0.13 */
134 	1014,	/* 0.14 */
135 	1013,	/* 0.15 */
136 	1011,	/* 0.16 */
137 	1010,	/* 0.17 */
138 	1008,	/* 0.18 */
139 	1006,	/* 0.19 */
140 	1004,	/* 0.20 */
141 	1002,	/* 0.21 */
142 	1000,	/* 0.22 */
143 	998,	/* 0.23 */
144 	996,	/* 0.24 */
145 	993,	/* 0.25 */
146 	991,	/* 0.26 */
147 	989,	/* 0.27 */
148 	986,	/* 0.28 */
149 	983,	/* 0.29 */
150 	981,	/* 0.30 */
151 	978,	/* 0.31 */
152 	975,	/* 0.32 */
153 	972,	/* 0.33 */
154 	969,	/* 0.34 */
155 	967,	/* 0.35 */
156 	963,	/* 0.36 */
157 	960,	/* 0.37 */
158 	957,	/* 0.38 */
159 	954,	/* 0.39 */
160 	951,	/* 0.40 */
161 	947,	/* 0.41 */
162 	944,	/* 0.42 */
163 	941,	/* 0.43 */
164 	937,	/* 0.44 */
165 	934,	/* 0.45 */
166 	930,	/* 0.46 */
167 	927,	/* 0.47 */
168 	923,	/* 0.48 */
169 	920,	/* 0.49 */
170 	916,	/* 0.50 */
171 	912,	/* 0.51 */
172 	909,	/* 0.52 */
173 	905,	/* 0.53 */
174 	901,	/* 0.54 */
175 	897,	/* 0.55 */
176 	893,	/* 0.56 */
177 	890,	/* 0.57 */
178 	886,	/* 0.58 */
179 	882,	/* 0.59 */
180 	878,	/* 0.60 */
181 	874,	/* 0.61 */
182 	870,	/* 0.62 */
183 	866,	/* 0.63 */
184 	862,	/* 0.64 */
185 	859,	/* 0.65 */
186 	855,	/* 0.66 */
187 	851,	/* 0.67 */
188 	847,	/* 0.68 */
189 	843,	/* 0.69 */
190 	839,	/* 0.70 */
191 	835,	/* 0.71 */
192 	831,	/* 0.72 */
193 	827,	/* 0.73 */
194 	823,	/* 0.74 */
195 	819,	/* 0.75 */
196 	815,	/* 0.76 */
197 	811,	/* 0.77 */
198 	807,	/* 0.78 */
199 	804,	/* 0.79 */
200 	800,	/* 0.80 */
201 	796,	/* 0.81 */
202 	792,	/* 0.82 */
203 	788,	/* 0.83 */
204 	784,	/* 0.84 */
205 	780,	/* 0.85 */
206 	776,	/* 0.86 */
207 	773,	/* 0.87 */
208 	769,	/* 0.88 */
209 	765,	/* 0.89 */
210 	761,	/* 0.90 */
211 	757,	/* 0.91 */
212 	754,	/* 0.92 */
213 	750,	/* 0.93 */
214 	746,	/* 0.94 */
215 	742,	/* 0.95 */
216 	739,	/* 0.96 */
217 	735,	/* 0.97 */
218 	731,	/* 0.98 */
219 	728,	/* 0.99 */
220 	724,	/* 1.00 */
221 	720,	/* 1.01 */
222 };
223 
224 void
icossin2(int x,int y,int * cosp,int * sinp)225 icossin2(int x, int y, int *cosp, int *sinp)
226 {
227 	int sinsign, cossign, tan, tan10, rem;
228 	short *stp, *ctp;
229 
230 	if(x == 0){
231 		if(y >= 0)
232 			*sinp = ICOSSCALE, *cosp = 0;
233 		else
234 			*sinp = -ICOSSCALE, *cosp = 0;
235 		return;
236 	}
237 	sinsign = cossign = 1;
238 	if(x < 0){
239 		cossign = -1;
240 		x = -x;
241 	}
242 	if(y < 0){
243 		sinsign = -1;
244 		y = -y;
245 	}
246 	if(y > x){
247 		tan = 1000*x/y;
248 		tan10 = tan/10;
249 		stp = &cosinus[tan10];
250 		ctp = &sinus[tan10];
251 	}else{
252 		tan = 1000*y/x;
253 		tan10 = tan/10;
254 		stp = &sinus[tan10];
255 		ctp = &cosinus[tan10];
256 	}
257 	rem = tan-(tan10*10);
258 	*sinp = sinsign*(stp[0]+(stp[1]-stp[0])*rem/10);
259 	*cosp = cossign*(ctp[0]+(ctp[1]-ctp[0])*rem/10);
260 }
261