Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OOHPVector.h
Go to the documentation of this file.
1/*
2
3OOHPVector.h
4
5Mathematical framework for Oolite.
6High-precision vectors for world-space coordinates
7
8Oolite
9Copyright (C) 2004-2013 Giles C Williams and contributors
10
11This program is free software; you can redistribute it and/or
12modify it under the terms of the GNU General Public License
13as published by the Free Software Foundation; either version 2
14of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24MA 02110-1301, USA.
25
26*/
27
28
29#ifndef INCLUDED_OOMATHS_h
30 #error Do not include OOHPVector.h directly; include OOMaths.h.
31#else
32
33
34#ifndef OOMATHS_EXTERNAL_VECTOR_TYPES
35
36typedef struct HPVector
37{
40 OOHPScalar z;
41} HPVector;
42
43
44typedef struct HPVector2D
45{
48} HPVector2D;
49
50#endif
51
52
53extern const HPVector kZeroHPVector, /* 0, 0, 0 */
54 kBasisXHPVector, /* 1, 0, 0 */
55 kBasisYHPVector, /* 0, 1, 0 */
56 kBasisZHPVector; /* 0, 0, 1 */
57
58
59extern const HPVector2D kZeroHPVector2D, /* 0, 0 */
60 kBasisXHPVector2D, /* 1, 0 */
61 kBasisYHPVector2D; /* 0, 1 */
62
63
64/* Construct vector */
65OOINLINE HPVector make_HPvector(OOHPScalar vx, OOHPScalar vy, OOHPScalar vz) INLINE_CONST_FUNC;
66OOINLINE HPVector2D MakeHPVector2D(OOHPScalar vx, OOHPScalar vy) INLINE_CONST_FUNC;
67
68OOINLINE HPVector vectorToHPVector(Vector v) INLINE_CONST_FUNC;
69OOINLINE Vector HPVectorToVector(HPVector v) INLINE_CONST_FUNC;
70
71#if !OOMATHS_STANDALONE
72/* Generate random vectors. */
73HPVector OORandomUnitHPVector(void);
74HPVector OOHPVectorRandomSpatial(OOHPScalar maxLength); // Random vector uniformly distributed in radius-maxLength sphere. (Longer vectors are more common.)
75HPVector OOHPVectorRandomRadial(OOHPScalar maxLength); // Random vector with uniform distribution of direction and radius in radius-maxLength sphere. (Causes clustering at centre.)
76HPVector OORandomPositionInCylinder(HPVector centre1, OOHPScalar exclusion1, HPVector centre2, OOHPScalar exclusion2, OOHPScalar radius);
77HPVector OORandomPositionInShell(HPVector centre, OOHPScalar inner, OOHPScalar outer);
78/* returns the projection of 'point' to the plane defined by the point
79 'plane' and the normal vector 'normal' */
80HPVector OOProjectHPVectorToPlane(HPVector point, HPVector plane, HPVector normal);
81#endif
82
83
84/* Multiply vector by scalar (in place) */
85OOINLINE void HPscale_vector(HPVector *outHPVector, OOHPScalar factor) ALWAYS_INLINE_FUNC NONNULL_FUNC;
86
87/* Multiply vector by scalar */
88OOINLINE HPVector HPvector_multiply_scalar(HPVector v, OOHPScalar s) INLINE_CONST_FUNC;
89
90/* Addition and subtraction of vectors */
91OOINLINE HPVector HPvector_add(HPVector a, HPVector b) INLINE_CONST_FUNC;
92OOINLINE HPVector HPvector_subtract(HPVector a, HPVector b) INLINE_CONST_FUNC;
93#define HPvector_between(a, b) HPvector_subtract(b, a)
94OOINLINE HPVector HPvector_flip(HPVector v) INLINE_CONST_FUNC;
95
96/* HPVector linear interpolation */
97OOINLINE HPVector OOHPVectorInterpolate(HPVector a, HPVector b, OOHPScalar where) INLINE_CONST_FUNC;
98OOINLINE HPVector OOHPVectorTowards(HPVector a, HPVector b, OOHPScalar where) INLINE_CONST_FUNC;
99
100/* Comparison of vectors */
101OOINLINE bool HPvector_equal(HPVector a, HPVector b) INLINE_CONST_FUNC;
102
103/* Square of magnitude of vector */
104OOINLINE OOHPScalar HPmagnitude2(HPVector vec) INLINE_CONST_FUNC;
105
106/* Magnitude of vector */
107OOINLINE OOHPScalar HPmagnitude(HPVector vec) INLINE_CONST_FUNC;
108
109/* Normalize vector */
110OOINLINE HPVector HPvector_normal(HPVector vec) INLINE_CONST_FUNC;
111
112/* Normalize vector, returning fallback if zero vector. */
113OOINLINE HPVector HPvector_normal_or_fallback(HPVector vec, HPVector fallback) INLINE_CONST_FUNC;
114OOINLINE HPVector HPvector_normal_or_xbasis(HPVector vec) INLINE_CONST_FUNC;
115OOINLINE HPVector HPvector_normal_or_ybasis(HPVector vec) INLINE_CONST_FUNC;
116OOINLINE HPVector HPvector_normal_or_zbasis(HPVector vec) INLINE_CONST_FUNC;
117
118/* Square of distance between vectors */
119OOINLINE OOHPScalar HPdistance2(HPVector v1, HPVector v2) INLINE_CONST_FUNC;
120
121/* Distance between vectors */
122OOINLINE OOHPScalar HPdistance(HPVector v1, HPVector v2) INLINE_CONST_FUNC;
123
124/* Dot product */
125OOINLINE OOHPScalar HPdot_product (HPVector first, HPVector second) INLINE_CONST_FUNC;
126
127/* NORMALIZED cross product */
128OOINLINE HPVector HPcross_product(HPVector first, HPVector second) INLINE_CONST_FUNC;
129
130/* General cross product */
131OOINLINE HPVector HPtrue_cross_product(HPVector first, HPVector second) CONST_FUNC;
132
133/* Triple product */
134OOINLINE OOHPScalar HPtriple_product(HPVector first, HPVector second, HPVector third) INLINE_CONST_FUNC;
135
136/* Given three points on a surface, returns the normal to the surface. */
137OOINLINE HPVector HPnormal_to_surface(HPVector v1, HPVector v2, HPVector v3) CONST_FUNC;
138
139#if __OBJC__
140NSString *HPVectorDescription(HPVector vector); // @"(x, y, z)"
141NSArray *ArrayFromHPVector(HPVector vector);
142
143#endif
144
145#if OOMATHS_OPENGL_INTEGRATION
146/* OpenGL conveniences. Need to be macros to work with OOMacroOpenGL. */
147#define GLVertexOOHPVector(v) do { HPVector v_ = v; glVertex3f(v_.x, v_.y, v_.z); } while (0)
148#define GLTranslateOOHPVector(v) do { HPVector v_ = v; OOGL(glTranslatef(v_.x, v_.y, v_.z)); } while (0)
149#endif
150
151
152/*** Only inline definitions beyond this point ***/
153
154OOINLINE HPVector make_HPvector (OOHPScalar vx, OOHPScalar vy, OOHPScalar vz)
155{
156 HPVector result;
157 result.x = vx;
158 result.y = vy;
159 result.z = vz;
160 return result;
161}
162
163
164OOINLINE HPVector2D MakeHPVector2D(OOHPScalar vx, OOHPScalar vy)
165{
166 HPVector2D result;
167 result.x = vx;
168 result.y = vy;
169 return result;
170}
171
172OOINLINE HPVector vectorToHPVector(Vector v) {
173 HPVector result;
174 result.x = (OOHPScalar)v.x;
175 result.y = (OOHPScalar)v.y;
176 result.z = (OOHPScalar)v.z;
177 return result;
178}
179
180OOINLINE Vector HPVectorToVector(HPVector v) {
181 Vector result;
182 result.x = (OOScalar)v.x;
183 result.y = (OOScalar)v.y;
184 result.z = (OOScalar)v.z;
185 return result;
186}
187
188OOINLINE void HPscale_vector(HPVector *vec, OOHPScalar factor)
189{
190 /*
191 Clang static analyzer: reports an unintialized value here when called
192 from -[HeadUpDisplay rescaleByFactor:]. This is blatantly wrong, as
193 the array the vector comes from is fully initialized in the range being
194 looped over.
195 -- Ahruman 2012-09-14
196 */
197 vec->x *= factor;
198 vec->y *= factor;
199 vec->z *= factor;
200}
201
202
203OOINLINE HPVector HPvector_multiply_scalar(HPVector v, OOHPScalar s)
204{
205 /*
206 Clang static analyzer: reports a garbage value here when called from
207 -[OOMesh rescaleByFactor:], apparently on baseless assumption that
208 OOMesh._vertices points to only one vertex.
209 -- Ahruman 2012-09-14
210 */
211 HPVector r;
212 r.x = v.x * s;
213 r.y = v.y * s;
214 r.z = v.z * s;
215 return r;
216}
217
218
219OOINLINE HPVector HPvector_add(HPVector a, HPVector b)
220{
221 HPVector r;
222 r.x = a.x + b.x;
223 r.y = a.y + b.y;
224 r.z = a.z + b.z;
225 return r;
226}
227
228
229OOINLINE HPVector OOHPVectorInterpolate(HPVector a, HPVector b, OOHPScalar where)
230{
231 return make_HPvector(OOLerpd(a.x, b.x, where),
232 OOLerpd(a.y, b.y, where),
233 OOLerpd(a.z, b.z, where));
234}
235
236
237OOINLINE HPVector OOHPVectorTowards(HPVector a, HPVector b, OOHPScalar where)
238{
239 return make_HPvector(a.x + b.x * where,
240 a.y + b.y * where,
241 a.z + b.z * where);
242}
243
244
245OOINLINE HPVector HPvector_subtract(HPVector a, HPVector b)
246{
247 HPVector r;
248 r.x = a.x - b.x;
249 r.y = a.y - b.y;
250 r.z = a.z - b.z;
251 return r;
252}
253
254
255OOINLINE HPVector HPvector_flip(HPVector v)
256{
257 return HPvector_subtract(kZeroHPVector, v);
258}
259
260
261OOINLINE bool HPvector_equal(HPVector a, HPVector b)
262{
263 return a.x == b.x && a.y == b.y && a.z == b.z;
264}
265
266
267OOINLINE OOHPScalar HPmagnitude2(HPVector vec)
268{
269 return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z;
270}
271
272
273OOINLINE OOHPScalar HPmagnitude(HPVector vec)
274{
275 return sqrt(HPmagnitude2(vec));
276}
277
278
279OOINLINE HPVector HPvector_normal_or_fallback(HPVector vec, HPVector fallback)
280{
281 OOHPScalar mag2 = HPmagnitude2(vec);
282 if (EXPECT_NOT(mag2 == 0.0)) return fallback;
283 return HPvector_multiply_scalar(vec, 1.0 / sqrt(mag2));
284}
285
286
287OOINLINE HPVector HPvector_normal_or_xbasis(HPVector vec)
288{
289 return HPvector_normal_or_fallback(vec, kBasisXHPVector);
290}
291
292
293OOINLINE HPVector HPvector_normal_or_ybasis(HPVector vec)
294{
295 return HPvector_normal_or_fallback(vec, kBasisYHPVector);
296}
297
298
299OOINLINE HPVector HPvector_normal_or_zbasis(HPVector vec)
300{
301 return HPvector_normal_or_fallback(vec, kBasisZHPVector);
302}
303
304
305OOINLINE HPVector HPvector_normal(HPVector vec)
306{
307 return HPvector_normal_or_fallback(vec, kZeroHPVector);
308}
309
310
311OOINLINE OOHPScalar HPdistance2(HPVector v1, HPVector v2)
312{
313 return HPmagnitude2(HPvector_subtract(v1, v2));
314}
315
316
317OOINLINE OOHPScalar HPdistance(HPVector v1, HPVector v2)
318{
319 return HPmagnitude(HPvector_subtract(v1, v2));
320}
321
322
323OOINLINE HPVector HPtrue_cross_product(HPVector first, HPVector second)
324{
325 HPVector result;
326 result.x = (first.y * second.z) - (first.z * second.y);
327 result.y = (first.z * second.x) - (first.x * second.z);
328 result.z = (first.x * second.y) - (first.y * second.x);
329 return result;
330}
331
332
333OOINLINE HPVector HPcross_product(HPVector first, HPVector second)
334{
335 return HPvector_normal(HPtrue_cross_product(first, second));
336}
337
338
339OOINLINE OOHPScalar HPdot_product (HPVector a, HPVector b)
340{
341 return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
342}
343
344
345OOINLINE OOHPScalar HPtriple_product(HPVector first, HPVector second, HPVector third)
346{
347 return HPdot_product(first, HPtrue_cross_product(second, third));
348}
349
350
351OOINLINE HPVector HPnormal_to_surface(HPVector v1, HPVector v2, HPVector v3)
352{
353 HPVector d0, d1;
354 d0 = HPvector_subtract(v2, v1);
355 d1 = HPvector_subtract(v3, v2);
356 return HPcross_product(d0, d1);
357}
358
359
360#endif /* INCLUDED_OOMATHS_h */
#define EXPECT_NOT(x)
#define ALWAYS_INLINE_FUNC
#define NONNULL_FUNC
#define INLINE_CONST_FUNC
#define OOINLINE
#define CONST_FUNC
const HPVector kBasisXHPVector
Definition OOHPVector.m:29
HPVector OOHPVectorRandomRadial(OOHPScalar maxLength)
Definition OOHPVector.m:98
HPVector OOProjectHPVectorToPlane(HPVector point, HPVector plane, HPVector normal)
Definition OOHPVector.m:141
HPVector OORandomPositionInShell(HPVector centre, OOHPScalar inner, OOHPScalar outer)
Definition OOHPVector.m:130
const HPVector2D kBasisYHPVector2D
Definition OOHPVector.m:35
const HPVector kBasisYHPVector
Definition OOHPVector.m:30
const HPVector kZeroHPVector
Definition OOHPVector.m:28
HPVector OORandomUnitHPVector(void)
Definition OOHPVector.m:66
const HPVector2D kBasisXHPVector2D
Definition OOHPVector.m:34
HPVector OOHPVectorRandomSpatial(OOHPScalar maxLength)
Definition OOHPVector.m:82
const HPVector2D kZeroHPVector2D
Definition OOHPVector.m:33
const HPVector kBasisZHPVector
Definition OOHPVector.m:31
HPVector OORandomPositionInCylinder(HPVector centre1, OOHPScalar exclusion1, HPVector centre2, OOHPScalar exclusion2, OOHPScalar radius)
Definition OOHPVector.m:113
double OOHPScalar
Definition OOMaths.h:69
GLfloat OOScalar
Definition OOMaths.h:64
float y
float x