1 /*******************************************************************************
2  * vector.h
3  *
4  * This module contains macros to perform operations on vectors.
5  *
6  * ---------------------------------------------------------------------------
7  * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
8  * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
9  *
10  * POV-Ray is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Affero General Public License as
12  * published by the Free Software Foundation, either version 3 of the
13  * License, or (at your option) any later version.
14  *
15  * POV-Ray is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Affero General Public License for more details.
19  *
20  * You should have received a copy of the GNU Affero General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  * ---------------------------------------------------------------------------
23  * POV-Ray is based on the popular DKB raytracer version 2.12.
24  * DKBTrace was originally written by David K. Buck.
25  * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
26  * ---------------------------------------------------------------------------
27  * $File: //depot/public/povray/3.x/source/backend/math/vector.h $
28  * $Revision: #1 $
29  * $Change: 6069 $
30  * $DateTime: 2013/11/06 11:59:40 $
31  * $Author: chrisc $
32  *******************************************************************************/
33 
34 #ifndef VECTOR_H
35 #define VECTOR_H
36 
37 #include "backend/frame.h"
38 
39 namespace pov
40 {
41 
42 /*****************************************************************************
43 * Inline functions
44 ******************************************************************************/
45 
46 // Vector Add
VAdd(VECTOR a,const VECTOR b,const VECTOR c)47 inline void VAdd(VECTOR a, const VECTOR b, const VECTOR c)
48 {
49 	a[X] = b[X] + c[X];
50 	a[Y] = b[Y] + c[Y];
51 	a[Z] = b[Z] + c[Z];
52 }
53 
VAdd(SNGL_VECT a,const VECTOR b,const VECTOR c)54 inline void VAdd(SNGL_VECT a, const VECTOR b, const VECTOR c)
55 {
56 	a[X] = b[X] + c[X];
57 	a[Y] = b[Y] + c[Y];
58 	a[Z] = b[Z] + c[Z];
59 }
60 
VAdd(SNGL_VECT a,const SNGL_VECT b,const SNGL_VECT c)61 inline void VAdd(SNGL_VECT a, const SNGL_VECT b, const SNGL_VECT c)
62 {
63 	a[X] = b[X] + c[X];
64 	a[Y] = b[Y] + c[Y];
65 	a[Z] = b[Z] + c[Z];
66 }
67 
VAddEq(VECTOR a,const VECTOR b)68 inline void VAddEq(VECTOR a, const VECTOR b)
69 {
70 	a[X] += b[X];
71 	a[Y] += b[Y];
72 	a[Z] += b[Z];
73 }
74 
VAddEq(SNGL_VECT a,const VECTOR b)75 inline void VAddEq(SNGL_VECT a, const VECTOR b)
76 {
77 	a[X] += b[X];
78 	a[Y] += b[Y];
79 	a[Z] += b[Z];
80 }
81 
VAddEq(SNGL_VECT a,const SNGL_VECT b)82 inline void VAddEq(SNGL_VECT a, const SNGL_VECT b)
83 {
84 	a[X] += b[X];
85 	a[Y] += b[Y];
86 	a[Z] += b[Z];
87 }
88 
89 // Vector Subtract
VSub(VECTOR a,const VECTOR b,const VECTOR c)90 inline void VSub(VECTOR a, const VECTOR b, const VECTOR c)
91 {
92 	a[X] = b[X] - c[X];
93 	a[Y] = b[Y] - c[Y];
94 	a[Z] = b[Z] - c[Z];
95 }
96 
VSub(SNGL_VECT a,const VECTOR b,const VECTOR c)97 inline void VSub(SNGL_VECT a, const VECTOR b, const VECTOR c)
98 {
99 	a[X] = b[X] - c[X];
100 	a[Y] = b[Y] - c[Y];
101 	a[Z] = b[Z] - c[Z];
102 }
103 
VSub(VECTOR a,const SNGL_VECT b,const VECTOR c)104 inline void VSub(VECTOR a, const SNGL_VECT b, const VECTOR c)
105 {
106 	a[X] = b[X] - c[X];
107 	a[Y] = b[Y] - c[Y];
108 	a[Z] = b[Z] - c[Z];
109 }
110 
VSub(VECTOR a,const VECTOR b,const SNGL_VECT c)111 inline void VSub(VECTOR a, const VECTOR b, const SNGL_VECT c)
112 {
113 	a[X] = b[X] - c[X];
114 	a[Y] = b[Y] - c[Y];
115 	a[Z] = b[Z] - c[Z];
116 }
117 
VSub(VECTOR a,const SNGL_VECT b,const SNGL_VECT c)118 inline void VSub(VECTOR a, const SNGL_VECT b, const SNGL_VECT c)
119 {
120 	a[X] = b[X] - c[X];
121 	a[Y] = b[Y] - c[Y];
122 	a[Z] = b[Z] - c[Z];
123 }
124 
VSub(SNGL_VECT a,const SNGL_VECT b,const SNGL_VECT c)125 inline void VSub(SNGL_VECT a, const SNGL_VECT b, const SNGL_VECT c)
126 {
127 	a[X] = b[X] - c[X];
128 	a[Y] = b[Y] - c[Y];
129 	a[Z] = b[Z] - c[Z];
130 }
131 
VSubEq(VECTOR a,const VECTOR b)132 inline void VSubEq(VECTOR a, const VECTOR b)
133 {
134 	a[X] -= b[X];
135 	a[Y] -= b[Y];
136 	a[Z] -= b[Z];
137 }
138 
VSubEq(SNGL_VECT a,const VECTOR b)139 inline void VSubEq(SNGL_VECT a, const VECTOR b)
140 {
141 	a[X] -= b[X];
142 	a[Y] -= b[Y];
143 	a[Z] -= b[Z];
144 }
145 
VSubEq(SNGL_VECT a,const SNGL_VECT b)146 inline void VSubEq(SNGL_VECT a, const SNGL_VECT b)
147 {
148 	a[X] -= b[X];
149 	a[Y] -= b[Y];
150 	a[Z] -= b[Z];
151 }
152 
153 // Scale - Multiply Vector by a Scalar
VScale(VECTOR a,const VECTOR b,DBL k)154 inline void VScale(VECTOR a, const VECTOR b, DBL k)
155 {
156 	a[X] = b[X] * k;
157 	a[Y] = b[Y] * k;
158 	a[Z] = b[Z] * k;
159 }
160 
161 // Scale - Multiply Vector by a Scalar
VScale(SNGL_VECT a,const VECTOR b,DBL k)162 inline void VScale(SNGL_VECT a, const VECTOR b, DBL k)
163 {
164 	a[X] = b[X] * k;
165 	a[Y] = b[Y] * k;
166 	a[Z] = b[Z] * k;
167 }
168 
VScale(SNGL_VECT a,const SNGL_VECT b,SNGL k)169 inline void VScale(SNGL_VECT a, const SNGL_VECT b, SNGL k)
170 {
171 	a[X] = b[X] * k;
172 	a[Y] = b[Y] * k;
173 	a[Z] = b[Z] * k;
174 }
175 
VScaleEq(VECTOR a,DBL k)176 inline void VScaleEq(VECTOR a, DBL k)
177 {
178 	a[X] *= k;
179 	a[Y] *= k;
180 	a[Z] *= k;
181 }
182 
VScaleEq(SNGL_VECT a,SNGL k)183 inline void VScaleEq(SNGL_VECT a, SNGL k)
184 {
185 	a[X] *= k;
186 	a[Y] *= k;
187 	a[Z] *= k;
188 }
189 
190 // Inverse Scale - Divide Vector by a Scalar
VInverseScale(VECTOR a,const VECTOR b,DBL k)191 inline void VInverseScale(VECTOR a, const VECTOR b, DBL k)
192 {
193 	DBL tmp = 1.0 / k;
194 	a[X] = b[X] * tmp;
195 	a[Y] = b[Y] * tmp;
196 	a[Z] = b[Z] * tmp;
197 }
198 
VInverseScale(SNGL_VECT a,const SNGL_VECT b,SNGL k)199 inline void VInverseScale(SNGL_VECT a, const SNGL_VECT b, SNGL k)
200 {
201 	SNGL tmp = 1.0 / k;
202 	a[X] = b[X] * tmp;
203 	a[Y] = b[Y] * tmp;
204 	a[Z] = b[Z] * tmp;
205 }
206 
VInverseScaleEq(VECTOR a,DBL k)207 inline void VInverseScaleEq(VECTOR a, DBL k)
208 {
209 	DBL tmp = 1.0 / k;
210 	a[X] *= tmp;
211 	a[Y] *= tmp;
212 	a[Z] *= tmp;
213 }
214 
VInverseScaleEq(SNGL_VECT a,SNGL k)215 inline void VInverseScaleEq(SNGL_VECT a, SNGL k)
216 {
217 	SNGL tmp = 1.0 / k;
218 	a[X] *= tmp;
219 	a[Y] *= tmp;
220 	a[Z] *= tmp;
221 }
222 
223 // Dot Product - Gives Scalar angle (a) between two vectors (b) and (c)
VDot(DBL & a,const VECTOR b,const VECTOR c)224 inline void VDot(DBL& a, const VECTOR b, const VECTOR c)
225 {
226 	a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
227 }
228 
VDot(SNGL & a,const VECTOR b,const VECTOR c)229 inline void VDot(SNGL& a, const VECTOR b, const VECTOR c)
230 {
231 	a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
232 }
233 
VDot(DBL & a,const VECTOR b,const SNGL_VECT c)234 inline void VDot(DBL& a, const VECTOR b, const SNGL_VECT c)
235 {
236 	a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
237 }
238 
VDot(DBL & a,const SNGL_VECT b,const VECTOR c)239 inline void VDot(DBL& a, const SNGL_VECT b, const VECTOR c)
240 {
241 	a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
242 }
243 
VDot(DBL & a,const SNGL_VECT b,const SNGL_VECT c)244 inline void VDot(DBL& a, const SNGL_VECT b, const SNGL_VECT c)
245 {
246 	a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
247 }
248 
VDot(SNGL & a,const SNGL_VECT b,const SNGL_VECT c)249 inline void VDot(SNGL& a, const SNGL_VECT b, const SNGL_VECT c)
250 {
251 	a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
252 }
253 
254 // Cross Product - returns Vector (a) = (b) x (c)
VCross(VECTOR a,const VECTOR b,const VECTOR c)255 inline void VCross(VECTOR a, const VECTOR b, const VECTOR c)
256 {
257 	VECTOR tmp;
258 
259 	tmp[X] = b[Y] * c[Z] - b[Z] * c[Y];
260 	tmp[Y] = b[Z] * c[X] - b[X] * c[Z];
261 	tmp[Z] = b[X] * c[Y] - b[Y] * c[X];
262 
263 	Assign_Vector(a, tmp);
264 }
265 
266 // Evaluate - returns Vector (a) = Multiply Vector (b) by Vector (c)
VEvaluate(VECTOR a,const VECTOR b,const VECTOR c)267 inline void VEvaluate(VECTOR a, const VECTOR b, const VECTOR c)
268 {
269 	a[X] = b[X] * c[X];
270 	a[Y] = b[Y] * c[Y];
271 	a[Z] = b[Z] * c[Z];
272 }
273 
VEvaluateEq(VECTOR a,const VECTOR b)274 inline void VEvaluateEq(VECTOR a, const VECTOR b)
275 {
276 	a[X] *= b[X];
277 	a[Y] *= b[Y];
278 	a[Z] *= b[Z];
279 }
280 
281 // Divide - returns Vector (a) = Divide Vector (a) by Vector (b)
VDivEq(VECTOR a,const VECTOR b)282 inline void VDivEq(VECTOR a, const VECTOR b)
283 {
284 	a[X] /= b[X];
285 	a[Y] /= b[Y];
286 	a[Z] /= b[Z];
287 }
288 
289 // Simple Scalar Square Macro
Sqr(DBL a)290 inline DBL Sqr(DBL a)
291 {
292 	return a * a;
293 }
294 
Sqr(SNGL a)295 inline SNGL Sqr(SNGL a)
296 {
297 	return a * a;
298 }
299 
300 // Vector Length - returs Scalar Euclidean Length (a) of Vector (b)
VLength(DBL & a,const VECTOR b)301 inline void VLength(DBL& a, const VECTOR b)
302 {
303 	a = sqrt(b[X] * b[X] + b[Y] * b[Y] + b[Z] * b[Z]);
304 }
305 
VLength(SNGL & a,const SNGL_VECT b)306 inline void VLength(SNGL& a, const SNGL_VECT b)
307 {
308 	a = sqrt(b[X] * b[X] + b[Y] * b[Y] + b[Z] * b[Z]);
309 }
310 
311 // Vector Distance - returs Scalar Euclidean Distance (a) between two points/Vectors (b) and (c)
VDist(DBL & a,const VECTOR b,const VECTOR c)312 inline void VDist(DBL& a, const VECTOR b, const VECTOR c)
313 {
314 	VECTOR tmp;
315 	VSub(tmp, b, c);
316 	VLength(a, tmp);
317 }
318 
319 // Normalize a Vector - returns a vector (length of 1) that points at (b)
VNormalize(VECTOR a,const VECTOR b)320 inline void VNormalize(VECTOR a, const VECTOR b)
321 {
322 	DBL tmp;
323 	VLength(tmp, b);
324 	VInverseScale(a, b, tmp);
325 }
326 
VNormalize(SNGL_VECT a,const SNGL_VECT b)327 inline void VNormalize(SNGL_VECT a, const SNGL_VECT b)
328 {
329 	SNGL tmp;
330 	VLength(tmp, b);
331 	VInverseScale(a, b, tmp);
332 }
333 
VNormalizeEq(VECTOR a)334 inline void VNormalizeEq(VECTOR a)
335 {
336 	DBL tmp;
337 	VLength(tmp, a);
338 	VInverseScaleEq(a, tmp);
339 }
340 
341 // Compute a Vector (a) Halfway Between Two Given Vectors (b) and (c)
VHalf(VECTOR a,const VECTOR b,const VECTOR c)342 inline void VHalf(VECTOR a, const VECTOR b, const VECTOR c)
343 {
344 	a[X] = 0.5 * (b[X] + c[X]);
345 	a[Y] = 0.5 * (b[Y] + c[Y]);
346 	a[Z] = 0.5 * (b[Z] + c[Z]);
347 }
348 
349 // Calculate the sum of the sqares of the components of a vector.  (the square of its length)
VSumSqr(const VECTOR a)350 inline DBL VSumSqr(const VECTOR a)
351 {
352 	return a[X] * a[X] + a[Y] * a[Y] + a[Z] * a[Z];
353 }
354 
355 // Linear combination of 2 vectors. [DB 7/94]
356 //   v = k1 * v1 + k2 * v2
VLinComb2(VECTOR v,DBL k1,const VECTOR v1,DBL k2,const VECTOR v2)357 inline void VLinComb2(VECTOR v, DBL k1, const VECTOR v1, DBL k2, const VECTOR v2)
358 {
359 	v[X] = k1 * v1[X] + k2 * v2[X];
360 	v[Y] = k1 * v1[Y] + k2 * v2[Y];
361 	v[Z] = k1 * v1[Z] + k2 * v2[Z];
362 }
363 
364 // Linear combination of 3 vectors. [DB 7/94]
365 //   v = k1 * v1 + k2 * v2 + k3 * v3
VLinComb3(VECTOR v,DBL k1,const VECTOR v1,DBL k2,const VECTOR v2,DBL k3,const VECTOR v3)366 inline void VLinComb3(VECTOR v, DBL k1, const VECTOR v1, DBL k2, const VECTOR v2, DBL k3, const VECTOR v3)
367 {
368 	v[X] = k1 * v1[X] + k2 * v2[X] + k3 * v3[X];
369 	v[Y] = k1 * v1[Y] + k2 * v2[Y] + k3 * v3[Y];
370 	v[Z] = k1 * v1[Z] + k2 * v2[Z] + k3 * v3[Z];
371 }
372 
373 // Evaluate a ray equation. [DB 7/94]
374 //   IPoint = Origin + depth * Direction
VEvaluateRay(VECTOR IPoint,const VECTOR Origin,DBL depth,const VECTOR Direction)375 inline void VEvaluateRay(VECTOR IPoint, const VECTOR Origin, DBL depth, const VECTOR Direction)
376 {
377 	IPoint[X] = Origin[X] + depth * Direction[X];
378 	IPoint[Y] = Origin[Y] + depth * Direction[Y];
379 	IPoint[Z] = Origin[Z] + depth * Direction[Z];
380 }
381 
382 // Add a scaled vector. [DB 7/94]
383 //   v  = v1 + k * v2;
384 //   v += k * v2;
VAddScaled(VECTOR v,const VECTOR v1,DBL k,const VECTOR v2)385 inline void VAddScaled(VECTOR v, const VECTOR v1, DBL k, const VECTOR v2)
386 {
387 	v[X] = v1[X] + k * v2[X];
388 	v[Y] = v1[Y] + k * v2[Y];
389 	v[Z] = v1[Z] + k * v2[Z];
390 }
391 
VAddScaledEq(VECTOR v,DBL k,const VECTOR v2)392 inline void VAddScaledEq(VECTOR v, DBL k, const VECTOR v2)
393 {
394 	v[X] += k * v2[X];
395 	v[Y] += k * v2[Y];
396 	v[Z] += k * v2[Z];
397 }
398 
399 // Inverse Scale - Divide Vector by a Scalar
V4D_InverseScaleEq(VECTOR_4D a,DBL k)400 inline void V4D_InverseScaleEq(VECTOR_4D a, DBL k)
401 {
402 	DBL tmp = 1.0 / k;
403 	a[X] *= tmp;
404 	a[Y] *= tmp;
405 	a[Z] *= tmp;
406 	a[T] *= tmp;
407 }
408 
409 // Dot Product - Gives Scalar angle (a) between two vectors (b) and (c)
V4D_Dot(DBL & a,const VECTOR_4D b,const VECTOR_4D c)410 inline void V4D_Dot(DBL& a, const VECTOR_4D b, const VECTOR_4D c)
411 {
412 	a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z] + b[T] * c[T];
413 }
414 
415 }
416 
417 #endif
418 
419 
420