1 /*
2  * Public domain.
3  * Operations on vectors in R^2 using scalar instructions.
4  */
5 
6 #include <agar/core/core.h>
7 #include <agar/math/m.h>
8 
9 const M_VectorOps2 mVecOps2_FPU = {
10 	"fpu",
11 	M_VectorZero2_FPU,
12 	M_VectorGet2_FPU,
13 	M_VectorSet2_FPU,
14 	M_VectorCopy2_FPU,
15 	M_VectorFlip2_FPU,
16 	M_VectorLen2_FPU,
17 	M_VectorLen2p_FPU,
18 	M_VectorDot2_FPU,
19 	M_VectorDot2p_FPU,
20 	M_VectorPerpDot2_FPU,
21 	M_VectorPerpDot2p_FPU,
22 	M_VectorDistance2_FPU,
23 	M_VectorDistance2p_FPU,
24 	M_VectorNorm2_FPU,
25 	M_VectorNorm2p_FPU,
26 	M_VectorNorm2v_FPU,
27 	M_VectorScale2_FPU,
28 	M_VectorScale2p_FPU,
29 	M_VectorScale2v_FPU,
30 	M_VectorAdd2_FPU,
31 	M_VectorAdd2p_FPU,
32 	M_VectorAdd2v_FPU,
33 	M_VectorSum2_FPU,
34 	M_VectorSub2_FPU,
35 	M_VectorSub2p_FPU,
36 	M_VectorSub2v_FPU,
37 	M_VectorAvg2_FPU,
38 	M_VectorAvg2p_FPU,
39 	M_VectorLERP2_FPU,
40 	M_VectorLERP2p_FPU,
41 	M_VectorElemPow2_FPU,
42 	M_VectorVecAngle2_FPU
43 };
44 
45 M_Vector2
M_VectorZero2_FPU(void)46 M_VectorZero2_FPU(void)
47 {
48 	M_Vector2 v;
49 
50 	v.x = 0.0;
51 	v.y = 0.0;
52 	return (v);
53 }
54 
55 M_Vector2
M_VectorGet2_FPU(M_Real x,M_Real y)56 M_VectorGet2_FPU(M_Real x, M_Real y)
57 {
58 	M_Vector2 v;
59 
60 	v.x = x;
61 	v.y = y;
62 	return (v);
63 }
64 
65 void
M_VectorSet2_FPU(M_Vector2 * v,M_Real x,M_Real y)66 M_VectorSet2_FPU(M_Vector2 *v, M_Real x, M_Real y)
67 {
68 	v->x = x;
69 	v->y = y;
70 }
71 
72 void
M_VectorCopy2_FPU(M_Vector2 * vDst,const M_Vector2 * vSrc)73 M_VectorCopy2_FPU(M_Vector2 *vDst, const M_Vector2 *vSrc)
74 {
75 	vDst->x = vSrc->x;
76 	vDst->y = vSrc->y;
77 }
78 
79 M_Vector2
M_VectorFlip2_FPU(M_Vector2 a)80 M_VectorFlip2_FPU(M_Vector2 a)
81 {
82 	M_Vector2 b;
83 
84 	b.x = -a.x;
85 	b.y = -a.y;
86 	return (b);
87 }
88 
89 M_Real
M_VectorLen2_FPU(M_Vector2 v)90 M_VectorLen2_FPU(M_Vector2 v)
91 {
92 	return Hypot2(v.x, v.y);
93 }
94 
95 M_Real
M_VectorLen2p_FPU(const M_Vector2 * v)96 M_VectorLen2p_FPU(const M_Vector2 *v)
97 {
98 	return Hypot2(v->x, v->y);
99 }
100 
101 M_Real
M_VectorDot2_FPU(M_Vector2 v1,M_Vector2 v2)102 M_VectorDot2_FPU(M_Vector2 v1, M_Vector2 v2)
103 {
104 	return (v1.x*v2.x + v1.y*v2.y);
105 }
106 
107 M_Real
M_VectorDot2p_FPU(const M_Vector2 * v1,const M_Vector2 * v2)108 M_VectorDot2p_FPU(const M_Vector2 *v1, const M_Vector2 *v2)
109 {
110 	return (v1->x*v2->x + v1->y*v2->y);
111 }
112 
113 M_Real
M_VectorPerpDot2_FPU(M_Vector2 v1,M_Vector2 v2)114 M_VectorPerpDot2_FPU(M_Vector2 v1, M_Vector2 v2)
115 {
116 	return (v1.x*v2.y - v1.y*v2.x);
117 }
118 
119 M_Real
M_VectorPerpDot2p_FPU(const M_Vector2 * v1,const M_Vector2 * v2)120 M_VectorPerpDot2p_FPU(const M_Vector2 *v1, const M_Vector2 *v2)
121 {
122 	return (v1->x*v2->y - v1->y*v2->x);
123 }
124 
125 M_Real
M_VectorDistance2_FPU(M_Vector2 a,M_Vector2 b)126 M_VectorDistance2_FPU(M_Vector2 a, M_Vector2 b)
127 {
128 	return M_VectorLen2_FPU( M_VectorSub2_FPU(a,b) );
129 }
130 
131 M_Real
M_VectorDistance2p_FPU(const M_Vector2 * a,const M_Vector2 * b)132 M_VectorDistance2p_FPU(const M_Vector2 *a, const M_Vector2 *b)
133 {
134 	return M_VectorLen2_FPU( M_VectorAdd2_FPU(*b,
135 	                         M_VectorFlip2_FPU(*a)) );
136 }
137 
138 M_Vector2
M_VectorNorm2_FPU(M_Vector2 v)139 M_VectorNorm2_FPU(M_Vector2 v)
140 {
141 	M_Vector2 n;
142 	M_Real len;
143 
144 	if ((len = M_VectorLen2p_FPU(&v)) == 0.0) {
145 		return (v);
146 	}
147 	n.x = v.x/len;
148 	n.y = v.y/len;
149 	return (n);
150 }
151 
152 M_Vector2
M_VectorNorm2p_FPU(const M_Vector2 * v)153 M_VectorNorm2p_FPU(const M_Vector2 *v)
154 {
155 	M_Vector2 n;
156 	M_Real len;
157 
158 	if ((len = M_VectorLen2p_FPU(v)) == 0.0) {
159 		return (*v);
160 	}
161 	n.x = v->x/len;
162 	n.y = v->y/len;
163 	return (n);
164 }
165 
166 void
M_VectorNorm2v_FPU(M_Vector2 * v)167 M_VectorNorm2v_FPU(M_Vector2 *v)
168 {
169 	M_Real len;
170 
171 	if ((len = M_VectorLen2p_FPU(v)) == 0.0) {
172 		return;
173 	}
174 	v->x /= len;
175 	v->y /= len;
176 }
177 
178 M_Vector2
M_VectorScale2_FPU(M_Vector2 a,M_Real c)179 M_VectorScale2_FPU(M_Vector2 a, M_Real c)
180 {
181 	M_Vector2 b;
182 
183 	b.x = a.x*c;
184 	b.y = a.y*c;
185 	return (b);
186 }
187 
188 M_Vector2
M_VectorScale2p_FPU(const M_Vector2 * a,M_Real c)189 M_VectorScale2p_FPU(const M_Vector2 *a, M_Real c)
190 {
191 	M_Vector2 b;
192 
193 	b.x = a->x*c;
194 	b.y = a->y*c;
195 	return (b);
196 }
197 
198 void
M_VectorScale2v_FPU(M_Vector2 * a,M_Real c)199 M_VectorScale2v_FPU(M_Vector2 *a, M_Real c)
200 {
201 	a->x *= c;
202 	a->y *= c;
203 }
204 
205 M_Vector2
M_VectorAdd2_FPU(M_Vector2 a,M_Vector2 b)206 M_VectorAdd2_FPU(M_Vector2 a, M_Vector2 b)
207 {
208 	M_Vector2 c;
209 
210 	c.x = a.x + b.x;
211 	c.y = a.y + b.y;
212 	return (c);
213 }
214 
215 M_Vector2
M_VectorAdd2p_FPU(const M_Vector2 * a,const M_Vector2 * b)216 M_VectorAdd2p_FPU(const M_Vector2 *a, const M_Vector2 *b)
217 {
218 	M_Vector2 c;
219 
220 	c.x = a->x + b->x;
221 	c.y = a->y + b->y;
222 	return (c);
223 }
224 
225 void
M_VectorAdd2v_FPU(M_Vector2 * r,const M_Vector2 * a)226 M_VectorAdd2v_FPU(M_Vector2 *r, const M_Vector2 *a)
227 {
228 	r->x += a->x;
229 	r->y += a->y;
230 }
231 
232 M_Vector2
M_VectorSum2_FPU(const M_Vector2 * va,Uint count)233 M_VectorSum2_FPU(const M_Vector2 *va, Uint count)
234 {
235 	M_Vector2 v;
236 	Uint i;
237 
238 	v.x = 0.0;
239 	v.y = 0.0;
240 	for (i = 0; i < count; i++) {
241 		v.x += va[i].x;
242 		v.y += va[i].y;
243 	}
244 	return (v);
245 }
246 
247 M_Vector2
M_VectorSub2_FPU(M_Vector2 a,M_Vector2 b)248 M_VectorSub2_FPU(M_Vector2 a, M_Vector2 b)
249 {
250 	M_Vector2 c;
251 
252 	c.x = a.x - b.x;
253 	c.y = a.y - b.y;
254 	return (c);
255 }
256 
257 M_Vector2
M_VectorSub2p_FPU(const M_Vector2 * a,const M_Vector2 * b)258 M_VectorSub2p_FPU(const M_Vector2 *a, const M_Vector2 *b)
259 {
260 	M_Vector2 c;
261 
262 	c.x = a->x - b->x;
263 	c.y = a->y - b->y;
264 	return (c);
265 }
266 
267 void
M_VectorSub2v_FPU(M_Vector2 * r,const M_Vector2 * a)268 M_VectorSub2v_FPU(M_Vector2 *r, const M_Vector2 *a)
269 {
270 	r->x -= a->x;
271 	r->y -= a->y;
272 }
273 
274 M_Vector2
M_VectorAvg2_FPU(M_Vector2 a,M_Vector2 b)275 M_VectorAvg2_FPU(M_Vector2 a, M_Vector2 b)
276 {
277 	M_Vector2 c;
278 
279 	c.x = (a.x + b.x)/2.0;
280 	c.y = (a.y + b.y)/2.0;
281 	return (c);
282 }
283 
284 M_Vector2
M_VectorAvg2p_FPU(const M_Vector2 * a,const M_Vector2 * b)285 M_VectorAvg2p_FPU(const M_Vector2 *a, const M_Vector2 *b)
286 {
287 	M_Vector2 c;
288 
289 	c.x = (a->x + b->x)/2.0;
290 	c.y = (a->y + b->y)/2.0;
291 	return (c);
292 }
293 
294 M_Vector2
M_VectorLERP2_FPU(M_Vector2 v1,M_Vector2 v2,M_Real t)295 M_VectorLERP2_FPU(M_Vector2 v1, M_Vector2 v2, M_Real t)
296 {
297 	M_Vector2 v;
298 
299 	v.x = v1.x + (v2.x - v1.x)*t;
300 	v.y = v1.y + (v2.y - v1.y)*t;
301 	return (v);
302 }
303 
304 M_Vector2
M_VectorLERP2p_FPU(M_Vector2 * v1,M_Vector2 * v2,M_Real t)305 M_VectorLERP2p_FPU(M_Vector2 *v1, M_Vector2 *v2, M_Real t)
306 {
307 	M_Vector2 v;
308 
309 	v.x = v1->x + (v2->x - v1->x)*t;
310 	v.y = v1->y + (v2->y - v1->y)*t;
311 	return (v);
312 }
313 
314 M_Vector2
M_VectorElemPow2_FPU(M_Vector2 v,M_Real p)315 M_VectorElemPow2_FPU(M_Vector2 v, M_Real p)
316 {
317 	M_Vector2 r;
318 
319 	r.x = Pow(v.x, p);
320 	r.y = Pow(v.y, p);
321 	return (r);
322 }
323 
324 M_Real
M_VectorVecAngle2_FPU(M_Vector2 vOrig,M_Vector2 vOther)325 M_VectorVecAngle2_FPU(M_Vector2 vOrig, M_Vector2 vOther)
326 {
327 	M_Vector2 vd;
328 
329 	vd = M_VectorSub2p_FPU(&vOther, &vOrig);
330 	return (Atan2(vd.y, vd.x));
331 }
332