Line data Source code
1 0 : /*
2 :
3 : OOHPVector.m
4 :
5 : Oolite
6 : Copyright (C) 2004-2013 Giles C Williams and contributors
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License
10 : as published by the Free Software Foundation; either version 2
11 : of the License, or (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 : MA 02110-1301, USA.
22 :
23 : */
24 :
25 : #include "OOMaths.h"
26 :
27 :
28 0 : const HPVector kZeroHPVector = { 0.0, 0.0, 0.0 };
29 0 : const HPVector kBasisXHPVector = { 1.0, 0.0, 0.0 };
30 0 : const HPVector kBasisYHPVector = { 0.0, 1.0, 0.0 };
31 0 : const HPVector kBasisZHPVector = { 0.0, 0.0, 1.0 };
32 :
33 0 : const HPVector2D kZeroHPVector2D = { 0.0, 0.0 };
34 0 : const HPVector2D kBasisXHPVector2D = { 1.0, 0.0 };
35 0 : const HPVector2D kBasisYHPVector2D = { 0.0, 1.0 };
36 :
37 :
38 : #if __OBJC__
39 : NSString *HPVectorDescription(HPVector vector)
40 : {
41 : return [NSString stringWithFormat:@"(%g, %g, %g)", vector.x, vector.y, vector.z];
42 : }
43 :
44 : NSArray *ArrayFromHPVector(HPVector vec)
45 : {
46 : return [NSArray arrayWithObjects:[NSNumber numberWithDouble:vec.x],
47 : [NSNumber numberWithDouble:vec.y],
48 : [NSNumber numberWithDouble:vec.z],
49 : nil];
50 : }
51 :
52 : #endif
53 :
54 :
55 : #if !OOMATHS_STANDALONE
56 : /* This generates random vectors distrubuted evenly over the surface of the
57 : unit sphere. It does this the simple way, by generating vectors in the
58 : half-unit cube and rejecting those outside the half-unit sphere (and the
59 : zero vector), then normalizing the result. (Half-unit measures are used
60 : to avoid unnecessary multiplications of randf() values.)
61 :
62 : In principle, using three normally-distributed co-ordinates (and again
63 : normalizing the result) would provide the right result without looping, but
64 : I don't trust bellf() so I'll go with the simple approach for now.
65 : */
66 0 : HPVector OORandomUnitHPVector(void)
67 : {
68 : HPVector v;
69 : OOHPScalar m;
70 :
71 : do
72 : {
73 : v = make_HPvector(randf() - 0.5f, randf() - 0.5f, randf() - 0.5f);
74 : m = HPmagnitude2(v);
75 : }
76 : while (m > 0.25 || m == 0.0); // We're confining to a sphere of radius 0.5 using the sqared magnitude; 0.5 squared is 0.25.
77 :
78 : return HPvector_normal(v);
79 : }
80 :
81 :
82 0 : HPVector OOHPVectorRandomSpatial(OOHPScalar maxLength)
83 : {
84 : HPVector v;
85 : OOHPScalar m;
86 :
87 : do
88 : {
89 : v = make_HPvector(randf() - 0.5f, randf() - 0.5f, randf() - 0.5f);
90 : m = HPmagnitude2(v);
91 : }
92 : while (m > 0.25); // We're confining to a sphere of radius 0.5 using the sqared magnitude; 0.5 squared is 0.25.
93 :
94 : return HPvector_multiply_scalar(v, maxLength * 2.0); // 2.0 is to compensate for the 0.5-radius sphere.
95 : }
96 :
97 :
98 0 : HPVector OOHPVectorRandomRadial(OOHPScalar maxLength)
99 : {
100 : return HPvector_multiply_scalar(OORandomUnitHPVector(), randf() * maxLength);
101 : }
102 :
103 :
104 0 : HPVector OOHPRandomPositionInBoundingBox(BoundingBox bb)
105 : {
106 : HPVector result;
107 : result.x = (OOHPScalar)(bb.min.x + randf() * (bb.max.x - bb.min.x));
108 : result.y = (OOHPScalar)(bb.min.y + randf() * (bb.max.y - bb.min.y));
109 : result.z = (OOHPScalar)(bb.min.z + randf() * (bb.max.z - bb.min.z));
110 : return result;
111 : }
112 :
113 0 : HPVector OORandomPositionInCylinder(HPVector centre1, OOHPScalar exclusion1, HPVector centre2, OOHPScalar exclusion2, OOHPScalar radius)
114 : {
115 : OOHPScalar exc12 = exclusion1*exclusion1;
116 : OOHPScalar exc22 = exclusion2*exclusion2;
117 : if (HPdistance(centre1,centre2) < (exclusion1+exclusion2)*1.2)
118 : {
119 : OOLog(@"position.cylinder.error",@"Trying to generate cylinder position in range %f long with exclusions %f and %f",HPdistance(centre1,centre2),exclusion1,exclusion2);
120 : }
121 : HPVector result;
122 : do
123 : {
124 : result = HPvector_add(OOHPVectorInterpolate(centre1,centre2,randf()),OOHPVectorRandomSpatial(radius));
125 : }
126 : while(HPdistance2(result,centre1)<exc12 || HPdistance2(result,centre2)<exc22);
127 : return result;
128 : }
129 :
130 0 : HPVector OORandomPositionInShell(HPVector centre, OOHPScalar inner, OOHPScalar outer)
131 : {
132 : HPVector result;
133 : OOHPScalar inner2 = inner*inner;
134 : do
135 : {
136 : result = HPvector_add(centre,OOHPVectorRandomSpatial(outer));
137 : } while(HPdistance2(result,centre)<inner2);
138 : return result;
139 : }
140 :
141 0 : HPVector OOProjectHPVectorToPlane(HPVector point, HPVector plane, HPVector normal)
142 : {
143 : return HPvector_subtract(point,HPvector_multiply_scalar(normal,HPdot_product(HPvector_subtract(point, plane), normal)));
144 : }
145 :
146 : #endif
|