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