1 /** @file vector1.h Vector math (2D, 3D, 4D).
2  *
3  * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  * @authors Copyright © 2006-2013 Daniel Swanson <danij@dengine.net>
5  *
6  * @par License
7  * GPL: http://www.gnu.org/licenses/gpl.html
8  *
9  * <small>This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by the
11  * Free Software Foundation; either version 2 of the License, or (at your
12  * option) any later version. This program is distributed in the hope that it
13  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details. You should have received a copy of the GNU
16  * General Public License along with this program; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301 USA</small>
19  */
20 
21 #ifndef LIBDENG_VECTOR_H
22 #define LIBDENG_VECTOR_H
23 
24 #include "types.h"
25 #include "fixedpoint.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /**
32  * @defgroup vec2 2D Vectors
33  * @ingroup legacyMath
34  * @{
35  */
36 
37 // Floating-point.
38 typedef float vectorcompf_t;
39 typedef vectorcompf_t vec2f_t[2];
40 typedef float const const_pvec2f_t[2];
41 typedef vectorcompf_t *pvec2f_t;
42 
43 typedef vec2f_t *arvec2f_t;
44 typedef vec2f_t const *const_arvec2f_t;
45 
46 // Double floating-point.
47 typedef double vectorcompd_t;
48 typedef vectorcompd_t vec2d_t[2];
49 typedef double const const_pvec2d_t[2];
50 typedef vectorcompd_t *pvec2d_t;
51 
52 typedef vec2d_t *arvec2d_t;
53 typedef vec2d_t const *const_arvec2d_t;
54 
55 typedef vectorcompd_t const *pcvec2d_t; /// @todo Remove me
56 
57 DENG_PUBLIC void V2x_Set(fixed_t vec[2], fixed_t x, fixed_t y);
58 
59 DENG_PUBLIC fixed_t V2x_Intersection(fixed_t const v1[2], fixed_t const v1Delta[2], fixed_t const v2[2], fixed_t const v2Delta[2]);
60 
61 /// @return @c 0 or 1.
62 DENG_PUBLIC int V2x_PointOnLineSide(fixed_t const point[2], fixed_t const lineOrigin[2], fixed_t const lineDirection[2]);
63 
64 /**
65  * Set the vector's x and y components.
66  */
67 DENG_PUBLIC void V2f_Set(pvec2f_t vec, vectorcompf_t x, vectorcompf_t y);
68 
69 DENG_PUBLIC void V2f_SetFixed(pvec2f_t vec, fixed_t x, fixed_t y);
70 
71 /**
72  * 2-dimensional vector length.
73  */
74 DENG_PUBLIC float V2f_Length(const_pvec2f_t vec);
75 
76 /**
77  * The distance between two points.
78  */
79 DENG_PUBLIC float V2f_Distance(const_pvec2f_t a, const_pvec2f_t b);
80 
81 /**
82  * Normalize a 2-dimensional vector.
83  *
84  * @return  The length of the vector.
85  */
86 DENG_PUBLIC float V2f_Normalize(pvec2f_t vec);
87 
88 /**
89  * Make a copy of the source vector.
90  */
91 DENG_PUBLIC void V2f_Copy(pvec2f_t dest, const_pvec2f_t src);
92 DENG_PUBLIC void V2f_Copyd(pvec2f_t dest, const_pvec2d_t src);
93 
94 /**
95  * Multiply the vector by the scalar.
96  */
97 DENG_PUBLIC void V2f_Scale(pvec2f_t vector, float scalar);
98 
99 /**
100  * Rotate the vector by a radian angle.
101  */
102 DENG_PUBLIC void V2f_Rotate(pvec2f_t vec, float radians);
103 
104 /**
105  * Calculate the sum of two 2-dimensional vectors.
106  */
107 DENG_PUBLIC void V2f_Sum(pvec2f_t dest, const_pvec2f_t src1, const_pvec2f_t src2);
108 
109 /**
110  * Subtract src1 from src2, return result in 'dest'.
111  */
112 DENG_PUBLIC void V2f_Subtract(pvec2f_t dest, const_pvec2f_t src1, const_pvec2f_t src2);
113 
114 /**
115  * Calculate the dot product of the two vectors.
116  */
117 DENG_PUBLIC float V2f_DotProduct(const_pvec2f_t a, const_pvec2f_t b);
118 
119 /**
120  * Calculate the scalar projection of 'a' onto 'b': dot(a,b)/len(b)
121  */
122 DENG_PUBLIC float V2f_ScalarProject(const_pvec2f_t a, const_pvec2f_t b);
123 
124 /**
125  * Project 'a' onto 'b' and store the resulting vector to 'dest':
126  * dot(a,b)/dot(b,b)*b
127  */
128 DENG_PUBLIC float V2f_Project(pvec2f_t dest, const_pvec2f_t a, const_pvec2f_t b);
129 
130 /**
131  * @return  @c true, if the two vectors are parallel.
132  */
133 DENG_PUBLIC dd_bool V2f_IsParallel(const_pvec2f_t a, const_pvec2f_t b);
134 
135 /**
136  * @return  @c true, if the vector is a zero vector.
137  */
138 DENG_PUBLIC dd_bool V2f_IsZero(const_pvec2f_t vec);
139 
140 /**
141  * The line must be exactly one unit long!
142  */
143 DENG_PUBLIC float V2f_PointUnitLineDistance(const_pvec2f_t point, const_pvec2f_t linePoint, const_pvec2f_t lineDirection);
144 
145 /**
146  * Determine where the two lines cross each other.  Notice that the
147  * lines are defined with a point and a vector.
148  *
149  * @return  A scaling factor for the first line.
150  */
151 DENG_PUBLIC float V2f_Intersection(const_pvec2f_t p1, const_pvec2f_t delta1, const_pvec2f_t p2, const_pvec2f_t delta2, pvec2f_t point);
152 
153 /**
154  * Intersection of lines a->b and c->d.  Unlike V2f_Intersection(), the
155  * arguments are all points.
156  */
157 DENG_PUBLIC float V2f_Intercept(const_pvec2f_t a, const_pvec2f_t b, const_pvec2f_t c, const_pvec2f_t d, pvec2f_t point);
158 
159 /**
160  * @return  @c true, if the two lines intercept.
161  */
162 DENG_PUBLIC dd_bool V2f_Intercept2(const_pvec2f_t a, const_pvec2f_t b, const_pvec2f_t c, const_pvec2f_t d, pvec2f_t point, float *abFrac, float *cdFrac);
163 
164 /**
165  * Linear interpolation between a and b, by c.
166  */
167 DENG_PUBLIC void V2f_Lerp(pvec2f_t dest, const_pvec2f_t a, const_pvec2f_t b, float c);
168 
169 /**
170  * Left/top is the min-point.  Right/bottom is the max-point.
171  */
172 DENG_PUBLIC void V2f_InitBox(arvec2f_t box, const_pvec2f_t point);
173 
174 DENG_PUBLIC void V2f_AddToBox(arvec2f_t box, const_pvec2f_t point);
175 
176 DENG_PUBLIC void V2f_UniteBox(arvec2f_t box, arvec2f_t const other);
177 
178 DENG_PUBLIC void V2f_CopyBox(arvec2f_t dest, arvec2f_t const src);
179 DENG_PUBLIC void V2f_CopyBoxd(arvec2f_t dest, arvec2d_t const src);
180 
181 /**
182  * Set the vector's x and y components.
183  */
184 DENG_PUBLIC void V2d_Set(pvec2d_t vec, vectorcompd_t x, vectorcompd_t y);
185 
186 DENG_PUBLIC void V2d_SetFixed(pvec2d_t vec, fixed_t x, fixed_t y);
187 
188 /**
189  * 2-dimensional vector length.
190  */
191 DENG_PUBLIC double V2d_Length(const_pvec2d_t vector);
192 
193 /**
194  * The distance between two points.
195  */
196 DENG_PUBLIC double V2d_Distance(const_pvec2d_t a, const_pvec2d_t b);
197 
198 /**
199  * Normalize a 2-dimensional vector.
200  *
201  * @return  The length of the vector.
202  */
203 DENG_PUBLIC double V2d_Normalize(pvec2d_t vec);
204 
205 /**
206  * Make a copy of the source vector.
207  */
208 DENG_PUBLIC void V2d_Copy(pvec2d_t dest, const_pvec2d_t src);
209 DENG_PUBLIC void V2d_Copyf(pvec2d_t dest, const_pvec2f_t srcf);
210 
211 /**
212  * Multiply the vector by the scalar.
213  */
214 DENG_PUBLIC void V2d_Scale(pvec2d_t vector, double scalar);
215 
216 /**
217  * Rotate the vector by a radian angle.
218  */
219 DENG_PUBLIC void V2d_Rotate(pvec2d_t vec, double radians);
220 
221 /**
222  * Calculate the sum of two 2-dimensional vectors.
223  */
224 DENG_PUBLIC void V2d_Sum(pvec2d_t dest, const_pvec2d_t src1, const_pvec2d_t src2);
225 
226 /**
227  * Subtract src1 from src2, return result in 'dest'.
228  */
229 DENG_PUBLIC void V2d_Subtract(pvec2d_t dest, const_pvec2d_t src1, const_pvec2d_t src2);
230 
231 /**
232  * Distance from the line to a point.
233  */
234 DENG_PUBLIC double V2d_PointLineDistance(const_pvec2d_t point, const_pvec2d_t linePoint,
235     const_pvec2d_t lineDirection, double *offset);
236 
237 /**
238  * Compute the parallel distance from the line to a point.
239  */
240 DENG_PUBLIC double V2d_PointLineParaDistance(const_pvec2d_t point, const_pvec2d_t lineDirection,
241     double linePara, double lineLength);
242 
243 /**
244  * Compute the perpendicular distance from the line to a point.
245  */
246 DENG_PUBLIC double V2d_PointLinePerpDistance(const_pvec2d_t point, const_pvec2d_t lineDirection,
247     double linePerp, double lineLength);
248 
249 /**
250  * Determines on which side of line the point is.
251  *
252  * @param point  The point.
253  * @param lineOrigin  Point on the line (origin).
254  * @param lineDirection  Line angle delta (from origin -> out).
255  *
256  * @return @c <0 Point is to the left of the line.
257  *         @c =0 Point lies directly on the line.
258  *         @c >0 Point is to the right of the line.
259  */
260 DENG_PUBLIC double V2d_PointOnLineSide(const_pvec2d_t point, const_pvec2d_t lineOrigin,
261     const_pvec2d_t lineDirection);
262 
263 /**
264  * Determines on which side of line the point is.
265  *
266  * @param point  The point.
267  * @param lineDirection  Line angle delta (from origin -> out).
268  * @param linePerp  Perpendicular d of the line.
269  * @param lineLength  Length of the line.
270  * @param epsilon  Distance within which @a point is considered on top of the line.
271  *
272  * @return @c <0 Point is to the left of the line.
273  *         @c =0 Point lies directly on the line.
274  *         @c >0 Point is to the right of the line.
275  */
276 DENG_PUBLIC double V2d_PointOnLineSide2(const_pvec2d_t point, const_pvec2d_t lineDirection,
277     double linePerp, double lineLength, double epsilon);
278 
279 /**
280  * Calculate the dot product of the two vectors.
281  */
282 DENG_PUBLIC double V2d_DotProduct(const_pvec2d_t a, const_pvec2d_t b);
283 
284 /**
285  * Calculate the scalar projection of 'a' onto 'b': dot(a,b)/len(b)
286  */
287 DENG_PUBLIC double V2d_ScalarProject(const_pvec2d_t a, const_pvec2d_t b);
288 
289 /**
290  * Project 'a' onto 'b' and store the resulting vector to 'dest':
291  * dot(a,b)/dot(b,b)*b
292  */
293 DENG_PUBLIC double V2d_Project(pvec2d_t dest, const_pvec2d_t a, const_pvec2d_t b);
294 
295 DENG_PUBLIC double V2d_ProjectOnLine(pvec2d_t dest, const_pvec2d_t point,
296     const_pvec2d_t lineOrigin, const_pvec2d_t lineDirection);
297 
298 /**
299  * @return  @c true, if the two vectors are parallel.
300  */
301 DENG_PUBLIC dd_bool V2d_IsParallel(const_pvec2d_t a, const_pvec2d_t b);
302 
303 /**
304  * @return  @c true, if the vector is a zero vector.
305  */
306 DENG_PUBLIC dd_bool V2d_IsZero(const_pvec2d_t vec);
307 
308 /**
309  * Determine where the two lines cross each other.  Notice that the
310  * lines are defined with a point and a vector.
311  *
312  * @return  A scaling factor for the first line.
313  */
314 DENG_PUBLIC double V2d_Intersection(const_pvec2d_t p1, const_pvec2d_t delta1, const_pvec2d_t p2, const_pvec2d_t delta2, pvec2d_t point);
315 
316 /**
317  * Intersection of lines a->b and c->d.  Unlike V2d_Intersection(), the
318  * arguments are all points.
319  */
320 DENG_PUBLIC double V2d_Intercept(const_pvec2d_t a, const_pvec2d_t b, const_pvec2d_t c, const_pvec2d_t d, pvec2d_t point);
321 
322 /**
323  * @return  @c true, if the two lines intercept.
324  */
325 DENG_PUBLIC dd_bool V2d_Intercept2(const_pvec2d_t a, const_pvec2d_t b, const_pvec2d_t c, const_pvec2d_t d, pvec2d_t point, double *abFrac, double *cdFrac);
326 
327 /**
328  * Linear interpolation between a and b, by c.
329  */
330 DENG_PUBLIC void V2d_Lerp(pvec2d_t dest, const_pvec2d_t a, const_pvec2d_t b, double c);
331 
332 /**
333  * Left/top is the min-point.  Right/bottom is the max-point.
334  */
335 DENG_PUBLIC void V2d_InitBox(arvec2d_t box, const_pvec2d_t point);
336 DENG_PUBLIC void V2d_InitBoxXY(arvec2d_t box, double x, double y);
337 
338 DENG_PUBLIC void V2d_AddToBox(arvec2d_t box, const_pvec2d_t point);
339 DENG_PUBLIC void V2d_AddToBoxXY(arvec2d_t box, double x, double y);
340 
341 DENG_PUBLIC void V2d_UniteBox(arvec2d_t box, const_arvec2d_t other);
342 
343 DENG_PUBLIC void V2d_CopyBox(arvec2d_t dest, const_arvec2d_t src);
344 
345 /// @}
346 
347 /**
348  * @defgroup vec3 3D Vectors
349  * @ingroup legacyMath
350  * @{
351  */
352 
353 // Floating-point.
354 typedef vectorcompf_t vec3f_t[3];
355 typedef float const const_pvec3f_t[3];
356 typedef vectorcompf_t* pvec3f_t;
357 typedef vec3f_t* arvec3f_t;
358 
359 // Double floating-point.
360 typedef vectorcompd_t vec3d_t[3];
361 typedef double const const_pvec3d_t[3];
362 typedef vectorcompd_t* pvec3d_t;
363 typedef vec3d_t* arvec3d_t;
364 
365 /**
366  * Set the vector's x, y and z components.
367  */
368 DENG_PUBLIC void V3f_Set(pvec3f_t vec, vectorcompf_t x, vectorcompf_t y, vectorcompf_t z);
369 
370 DENG_PUBLIC void V3f_SetFixed(pvec3f_t vec, fixed_t x, fixed_t y, fixed_t z);
371 
372 /**
373  * 3-dimensional vector length.
374  */
375 DENG_PUBLIC float V3f_Length(const_pvec3f_t vec);
376 
377 /**
378  * The distance between two points.
379  */
380 DENG_PUBLIC float V3f_Distance(const_pvec3f_t a, const_pvec3f_t b);
381 
382 /**
383  * Normalize a 3-dimensional vector.
384  *
385  * @return  The length of the vector.
386  */
387 DENG_PUBLIC float V3f_Normalize(pvec3f_t vec);
388 
389 /**
390  * Make a copy of the source vector.
391  */
392 DENG_PUBLIC void V3f_Copy(pvec3f_t dest, const_pvec3f_t src);
393 DENG_PUBLIC void V3f_Copyd(pvec3f_t dest, const_pvec3d_t src);
394 
395 /**
396  * Multiply the vector by the scalar.
397  */
398 DENG_PUBLIC void V3f_Scale(pvec3f_t vec, float scalar);
399 
400 /**
401  * Calculate the sum of two 3-dimensional vectors.
402  */
403 DENG_PUBLIC void V3f_Sum(pvec3f_t dest, const_pvec3f_t src1, const_pvec3f_t src2);
404 
405 /**
406  * Subtract src1 from src2, return result in 'dest'.
407  */
408 DENG_PUBLIC void V3f_Subtract(pvec3f_t dest, const_pvec3f_t src1, const_pvec3f_t src2);
409 
410 /**
411  * Calculate the dot product of the two vectors.
412  */
413 DENG_PUBLIC float V3f_DotProduct(const_pvec3f_t a, const_pvec3f_t b);
414 
415 /**
416  * Calculate the cross product of two vectors.
417  *
418  * @param dest  Result will be written back here.
419  * @param a     First vector.
420  * @param b     Second vector.
421  */
422 DENG_PUBLIC void V3f_CrossProduct(pvec3f_t dest, const_pvec3f_t a, const_pvec3f_t b);
423 
424 DENG_PUBLIC void V3f_CrossProductd(pvec3f_t dest, const_pvec3d_t ad, const_pvec3d_t bd);
425 
426 /**
427  * Cross product of two vectors composed of three points.
428  *
429  * @param dest  Result will be written back here.
430  * @param v1  First vector.
431  * @param v2  Second vector.
432  * @param v3  Third vector.
433  */
434 DENG_PUBLIC void V3f_PointCrossProduct(pvec3f_t dest, const_pvec3f_t v1, const_pvec3f_t v2, const_pvec3f_t v3);
435 
436 /**
437  * Find the closest point in the plane, to an arbitary point.
438  *
439  * @param dest  Result will be written back here.
440  * @param planeNormal  The normalized plane normal.
441  * @param planePoint  A point already on the plane.
442  * @param arbPoint  The arbitrary point to find the closest point too.
443  *
444  * @return  Distance from the closest point on the plane to the specified arbitary point.
445  */
446 DENG_PUBLIC float V3f_ClosestPointOnPlane(pvec3f_t dest, const_pvec3f_t planeNormal, const_pvec3f_t planePoint, const_pvec3f_t arbPoint);
447 
448 /**
449  * Determine which axis of the given vector is the major.
450  */
451 DENG_PUBLIC int V3f_MajorAxis(const_pvec3f_t vec);
452 
453 /**
454  * @return  @c true, if the vector is a zero vector.
455  */
456 DENG_PUBLIC dd_bool V3f_IsZero(const_pvec3f_t vec);
457 
458 /**
459  * Linear interpolation between a and b, by c.
460  */
461 DENG_PUBLIC void V3f_Lerp(pvec3f_t dest, const_pvec3f_t a, const_pvec3f_t b, vectorcompf_t c);
462 
463 /**
464  * Given a normalized normal, construct up and right vectors, oriented about
465  * @a normal in our right-handed world coordinate space.
466  *
467  * @param tangent  The 'right' vector will be written back here.
468  * @param bitangent  The 'up' vector will be written back here.
469  * @param normal  Normal to construct tangents for.
470  */
471 DENG_PUBLIC void V3f_BuildTangents(pvec3f_t tangent, pvec3f_t bitangent, const_pvec3f_t normal);
472 
473 /**
474  * Set the vector's x, y and z components.
475  */
476 DENG_PUBLIC void V3d_Set(pvec3d_t vec, vectorcompd_t x, vectorcompd_t y, vectorcompd_t z);
477 
478 DENG_PUBLIC void V3d_SetFixed(pvec3d_t vec, fixed_t x, fixed_t y, fixed_t z);
479 
480 /**
481  * 3-dimensional vector length.
482  */
483 DENG_PUBLIC double V3d_Length(const_pvec3d_t vec);
484 
485 /**
486  * The distance between two points.
487  */
488 DENG_PUBLIC double V3d_Distance(const_pvec3d_t a, const_pvec3d_t b);
489 
490 /**
491  * Normalize a 3-dimensional vector.
492  *
493  * @return  The length of the vector.
494  */
495 DENG_PUBLIC double V3d_Normalize(pvec3d_t vec);
496 
497 /**
498  * Make a copy of the source vector.
499  */
500 DENG_PUBLIC void V3d_Copy(pvec3d_t dest, const_pvec3d_t src);
501 DENG_PUBLIC void V3d_Copyf(pvec3d_t dest, const_pvec3f_t src);
502 
503 /**
504  * Multiply the vector by the scalar.
505  */
506 DENG_PUBLIC void V3d_Scale(pvec3d_t vec, vectorcompd_t scalar);
507 
508 /**
509  * Calculate the sum of two 3-dimensional vectors.
510  */
511 DENG_PUBLIC void V3d_Sum(pvec3d_t dest, const_pvec3d_t src1, const_pvec3d_t src2);
512 
513 /**
514  * Subtract src1 from src2, return result in 'dest'.
515  */
516 DENG_PUBLIC void V3d_Subtract(pvec3d_t dest, const_pvec3d_t src1, const_pvec3d_t src2);
517 
518 /**
519  * Calculate the dot product of the two vectors.
520  */
521 DENG_PUBLIC double V3d_DotProduct(const_pvec3d_t a, const_pvec3d_t b);
522 DENG_PUBLIC double V3d_DotProductf(const_pvec3d_t a, const_pvec3f_t b);
523 
524 /**
525  * Calculate the cross product of two vectors.
526  *
527  * @param dest  Result will be written back here.
528  * @param src1  First vector.
529  * @param src2  Second vector.
530  */
531 DENG_PUBLIC void V3d_CrossProduct(pvec3d_t dest, const_pvec3d_t src1, const_pvec3d_t src2);
532 
533 /**
534  * Cross product of two vectors composed of three points.
535  *
536  * @param dest  Result will be written back here.
537  * @param v1  First vector.
538  * @param v2  Second vector.
539  * @param v3  Third vector.
540  */
541 DENG_PUBLIC void V3d_PointCrossProduct(pvec3d_t dest, const_pvec3d_t v1, const_pvec3d_t v2, const_pvec3d_t v3);
542 
543 /**
544  * Find the closest point in the plane, to an arbitary point.
545  *
546  * @param dest  Result will be written back here.
547  * @param planeNormal  The normalized plane normal.
548  * @param planePoint  A point already on the plane.
549  * @param arbPoint  The arbitrary point to find the closest point too.
550  *
551  * @return  Distance from the closest point on the plane to the specified arbitary point.
552  */
553 DENG_PUBLIC double V3d_ClosestPointOnPlane(pvec3d_t dest, const_pvec3d_t planeNormal, const_pvec3d_t planePoint, const_pvec3d_t arbPoint);
554 DENG_PUBLIC double V3d_ClosestPointOnPlanef(pvec3d_t dest, const_pvec3f_t planeNormalf, const_pvec3d_t planePoint, const_pvec3d_t arbPoint);
555 
556 /**
557  * Determine which axis of the given vector is the major.
558  */
559 int V3d_MajorAxis(const_pvec3d_t vec);
560 
561 /**
562  * @return  @c true, if the vector is a zero vector.
563  */
564 DENG_PUBLIC dd_bool V3d_IsZero(const_pvec3d_t vec);
565 
566 /**
567  * Linear interpolation between a and b, by c.
568  */
569 DENG_PUBLIC void V3d_Lerp(pvec3d_t dest, const_pvec3d_t a, const_pvec3d_t b, vectorcompd_t c);
570 
571 /**
572  * Given a normalized normal, construct up and right vectors, oriented about
573  * @a normal in our right-handed world coordinate space.
574  *
575  * @param tangent  The 'right' vector will be written back here.
576  * @param bitangent  The 'up' vector will be written back here.
577  * @param normal  Normal to construct tangents for.
578  */
579 DENG_PUBLIC void V3d_BuildTangents(pvec3d_t tangent, pvec3d_t bitangent, const_pvec3d_t normal);
580 
581 /// @}
582 
583 /**
584  * @defgroup vec4 4D Vectors
585  * @ingroup legacyMath
586  * @{
587  */
588 
589 typedef vectorcompf_t vec4f_t[4];
590 typedef float const *const_pvec4f_t;
591 typedef vectorcompf_t* pvec4f_t;
592 typedef vec4f_t* arvec4f_t;
593 
594 /**
595  * Set the vector's x, y, z and w components.
596  */
597 DENG_PUBLIC void V4f_Set(pvec4f_t vec, vectorcompf_t x, vectorcompf_t y, vectorcompf_t z, vectorcompf_t w);
598 
599 DENG_PUBLIC void V4f_SetFixed(pvec4f_t vec, fixed_t x, fixed_t y, fixed_t z, fixed_t w);
600 
601 /**
602  * 4-dimensional vector length.
603  */
604 DENG_PUBLIC float V4f_Length(const_pvec4f_t vec);
605 
606 /**
607  * The distance between two points.
608  */
609 DENG_PUBLIC float V4f_Distance(const_pvec4f_t a, const_pvec4f_t b);
610 
611 /**
612  * Normalize a 4-dimensional vector.
613  *
614  * @return  The length of the vector.
615  */
616 DENG_PUBLIC float V4f_Normalize(pvec4f_t vec);
617 
618 /**
619  * Make a copy of the source vector.
620  */
621 DENG_PUBLIC void V4f_Copy(pvec4f_t dest, const_pvec4f_t src);
622 
623 /**
624  * Multiply the vector by the scalar.
625  */
626 DENG_PUBLIC void V4f_Scale(pvec4f_t vec, float scalar);
627 
628 /**
629  * Calculate the sum of two 4-dimensional vectors.
630  */
631 DENG_PUBLIC void V4f_Sum(pvec4f_t dest, const_pvec4f_t src1, const_pvec4f_t src2);
632 
633 /**
634  * Subtract src1 from src2, return result in 'dest'.
635  */
636 DENG_PUBLIC void V4f_Subtract(pvec4f_t dest, const_pvec4f_t src1, const_pvec4f_t src2);
637 
638 /**
639  * @return  @c true, if the vector is a zero vector.
640  */
641 DENG_PUBLIC dd_bool V4f_IsZero(const_pvec4f_t vec);
642 
643 /**
644  * Linear interpolation between a and b, by c.
645  */
646 DENG_PUBLIC void V4f_Lerp(pvec4f_t dest, const_pvec4f_t a, const_pvec4f_t b, float c);
647 
648 typedef vectorcompd_t vec4d_t[4];
649 typedef double const *const_pvec4d_t;
650 typedef vectorcompd_t *pvec4d_t;
651 typedef vec4d_t *arvec4d_t;
652 
653 /**
654  * Set the vector's x, y, z and w components.
655  */
656 DENG_PUBLIC void V4d_Set(pvec4d_t vec, vectorcompd_t x, vectorcompd_t y, vectorcompd_t z, vectorcompd_t w);
657 
658 DENG_PUBLIC void V4d_SetFixed(pvec4d_t vec, fixed_t x, fixed_t y, fixed_t z, fixed_t w);
659 
660 /**
661  * 4-dimensional vector length.
662  */
663 DENG_PUBLIC double V4d_Length(const_pvec4d_t vec);
664 
665 /**
666  * The distance between two points.
667  */
668 DENG_PUBLIC double V4d_Distance(const_pvec4d_t a, const_pvec4d_t b);
669 
670 /**
671  * Normalize a 4-dimensional vector.
672  *
673  * @return  The length of the vector.
674  */
675 DENG_PUBLIC double V4d_Normalize(pvec4d_t vec);
676 
677 /**
678  * Make a copy of the source vector.
679  */
680 DENG_PUBLIC void V4d_Copy(pvec4d_t dest, const_pvec4d_t src);
681 
682 /**
683  * Multiply the vector by the scalar.
684  */
685 DENG_PUBLIC void V4d_Scale(pvec4d_t vec, double scalar);
686 
687 /**
688  * Calculate the sum of two 4-dimensional vectors.
689  */
690 DENG_PUBLIC void V4d_Sum(pvec4d_t dest, const_pvec4d_t src1, const_pvec4d_t src2);
691 
692 /**
693  * Subtract src1 from src2, return result in 'dest'.
694  */
695 DENG_PUBLIC void V4d_Subtract(pvec4d_t dest, const_pvec4d_t src1, const_pvec4d_t src2);
696 
697 /**
698  * @return  @c true, if the vector is a zero vector.
699  */
700 DENG_PUBLIC dd_bool V4d_IsZero(const_pvec4d_t vec);
701 
702 /**
703  * Linear interpolation between a and b, by c.
704  */
705 DENG_PUBLIC void V4d_Lerp(pvec4d_t dest, const_pvec4d_t a, const_pvec4d_t b, double c);
706 
707 /// @}
708 
709 #ifdef __cplusplus
710 } // extern "C"
711 #endif
712 
713 #endif // LIBDENG_VECTOR_H
714