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