1/*
2 * Vector3.h
3 * RVO2-3D Library
4 *
5 * Copyright 2008 University of North Carolina at Chapel Hill
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * https://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * Please send all bug reports to <geom@cs.unc.edu>.
20 *
21 * The authors may be contacted via:
22 *
23 * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha
24 * Dept. of Computer Science
25 * 201 S. Columbia St.
26 * Frederick P. Brooks, Jr. Computer Science Bldg.
27 * Chapel Hill, N.C. 27599-3175
28 * United States of America
29 *
30 * <https://gamma.cs.unc.edu/RVO2/>
31 */
32
33/**
34 * \file Vector3.h
35 * \brief Contains the Vector3 class.
36 */
37#ifndef RVO3D_VECTOR3_H_
38#define RVO3D_VECTOR3_H_
39
40#include <cmath>
41#include <cstddef>
42#include <ostream>
43
44namespace RVO3D {
45 /**
46 * \brief Defines a three-dimensional vector.
47 */
48 class Vector3 {
49 public:
50 /**
51 * \brief Constructs and initializes a three-dimensional vector instance to zero.
52 */
53 inline Vector3()
54 {
55 val_[0] = 0.0f;
56 val_[1] = 0.0f;
57 val_[2] = 0.0f;
58 }
59
60 /**
61 * \brief Constructs and initializes a three-dimensional vector from the specified three-dimensional vector.
62 * \param vector The three-dimensional vector containing the xyz-coordinates.
63 */
64 inline Vector3(const Vector3 &vector)
65 {
66 val_[0] = vector[0];
67 val_[1] = vector[1];
68 val_[2] = vector[2];
69 }
70
71 /**
72 * \brief Constructs and initializes a three-dimensional vector from the specified three-element array.
73 * \param val The three-element array containing the xyz-coordinates.
74 */
75 inline explicit Vector3(const float val[3])
76 {
77 val_[0] = val[0];
78 val_[1] = val[1];
79 val_[2] = val[2];
80 }
81
82 /**
83 * \brief Constructs and initializes a three-dimensional vector from the specified xyz-coordinates.
84 * \param x The x-coordinate of the three-dimensional vector.
85 * \param y The y-coordinate of the three-dimensional vector.
86 * \param z The z-coordinate of the three-dimensional vector.
87 */
88 inline Vector3(float x, float y, float z)
89 {
90 val_[0] = x;
91 val_[1] = y;
92 val_[2] = z;
93 }
94
95 /**
96 * \brief Returns the x-coordinate of this three-dimensional vector.
97 * \return The x-coordinate of the three-dimensional vector.
98 */
99 inline float x() const { return val_[0]; }
100
101 /**
102 * \brief Returns the y-coordinate of this three-dimensional vector.
103 * \return The y-coordinate of the three-dimensional vector.
104 */
105 inline float y() const { return val_[1]; }
106
107 /**
108 * \brief Returns the z-coordinate of this three-dimensional vector.
109 * \return The z-coordinate of the three-dimensional vector.
110 */
111 inline float z() const { return val_[2]; }
112
113 /**
114 * \brief Returns the specified coordinate of this three-dimensional vector.
115 * \param i The coordinate that should be returned (0 <= i < 3).
116 * \return The specified coordinate of the three-dimensional vector.
117 */
118 inline float operator[](size_t i) const { return val_[i]; }
119
120 /**
121 * \brief Returns a reference to the specified coordinate of this three-dimensional vector.
122 * \param i The coordinate to which a reference should be returned (0 <= i < 3).
123 * \return A reference to the specified coordinate of the three-dimensional vector.
124 */
125 inline float &operator[](size_t i) { return val_[i]; }
126
127 /**
128 * \brief Computes the negation of this three-dimensional vector.
129 * \return The negation of this three-dimensional vector.
130 */
131 inline Vector3 operator-() const
132 {
133 return Vector3(-val_[0], -val_[1], -val_[2]);
134 }
135
136 /**
137 * \brief Computes the dot product of this three-dimensional vector with the specified three-dimensional vector.
138 * \param vector The three-dimensional vector with which the dot product should be computed.
139 * \return The dot product of this three-dimensional vector with a specified three-dimensional vector.
140 */
141 inline float operator*(const Vector3 &vector) const
142 {
143 return val_[0] * vector[0] + val_[1] * vector[1] + val_[2] * vector[2];
144 }
145
146 /**
147 * \brief Computes the scalar multiplication of this three-dimensional vector with the specified scalar value.
148 * \param scalar The scalar value with which the scalar multiplication should be computed.
149 * \return The scalar multiplication of this three-dimensional vector with a specified scalar value.
150 */
151 inline Vector3 operator*(float scalar) const
152 {
153 return Vector3(val_[0] * scalar, val_[1] * scalar, val_[2] * scalar);
154 }
155
156 /**
157 * \brief Computes the scalar division of this three-dimensional vector with the specified scalar value.
158 * \param scalar The scalar value with which the scalar division should be computed.
159 * \return The scalar division of this three-dimensional vector with a specified scalar value.
160 */
161 inline Vector3 operator/(float scalar) const
162 {
163 const float invScalar = 1.0f / scalar;
164
165 return Vector3(val_[0] * invScalar, val_[1] * invScalar, val_[2] * invScalar);
166 }
167
168 /**
169 * \brief Computes the vector sum of this three-dimensional vector with the specified three-dimensional vector.
170 * \param vector The three-dimensional vector with which the vector sum should be computed.
171 * \return The vector sum of this three-dimensional vector with a specified three-dimensional vector.
172 */
173 inline Vector3 operator+(const Vector3 &vector) const
174 {
175 return Vector3(val_[0] + vector[0], val_[1] + vector[1], val_[2] + vector[2]);
176 }
177
178 /**
179 * \brief Computes the vector difference of this three-dimensional vector with the specified three-dimensional vector.
180 * \param vector The three-dimensional vector with which the vector difference should be computed.
181 * \return The vector difference of this three-dimensional vector with a specified three-dimensional vector.
182 */
183 inline Vector3 operator-(const Vector3 &vector) const
184 {
185 return Vector3(val_[0] - vector[0], val_[1] - vector[1], val_[2] - vector[2]);
186 }
187
188 /**
189 * \brief Tests this three-dimensional vector for equality with the specified three-dimensional vector.
190 * \param vector The three-dimensional vector with which to test for equality.
191 * \return True if the three-dimensional vectors are equal.
192 */
193 inline bool operator==(const Vector3 &vector) const
194 {
195 return val_[0] == vector[0] && val_[1] == vector[1] && val_[2] == vector[2];
196 }
197
198 /**
199 * \brief Tests this three-dimensional vector for inequality with the specified three-dimensional vector.
200 * \param vector The three-dimensional vector with which to test for inequality.
201 * \return True if the three-dimensional vectors are not equal.
202 */
203 inline bool operator!=(const Vector3 &vector) const
204 {
205 return val_[0] != vector[0] || val_[1] != vector[1] || val_[2] != vector[2];
206 }
207
208 /**
209 * \brief Sets the value of this three-dimensional vector to the scalar multiplication of itself with the specified scalar value.
210 * \param scalar The scalar value with which the scalar multiplication should be computed.
211 * \return A reference to this three-dimensional vector.
212 */
213 inline Vector3 &operator*=(float scalar)
214 {
215 val_[0] *= scalar;
216 val_[1] *= scalar;
217 val_[2] *= scalar;
218
219 return *this;
220 }
221
222 /**
223 * \brief Sets the value of this three-dimensional vector to the scalar division of itself with the specified scalar value.
224 * \param scalar The scalar value with which the scalar division should be computed.
225 * \return A reference to this three-dimensional vector.
226 */
227 inline Vector3 &operator/=(float scalar)
228 {
229 const float invScalar = 1.0f / scalar;
230
231 val_[0] *= invScalar;
232 val_[1] *= invScalar;
233 val_[2] *= invScalar;
234
235 return *this;
236 }
237
238 /**
239 * \brief Sets the value of this three-dimensional vector to the vector
240 * sum of itself with the specified three-dimensional vector.
241 * \param vector The three-dimensional vector with which the vector sum should be computed.
242 * \return A reference to this three-dimensional vector.
243 */
244 inline Vector3 &operator+=(const Vector3 &vector)
245 {
246 val_[0] += vector[0];
247 val_[1] += vector[1];
248 val_[2] += vector[2];
249
250 return *this;
251 }
252
253 /**
254 * \brief Sets the value of this three-dimensional vector to the vector difference of itself with the specified three-dimensional vector.
255 * \param vector The three-dimensional vector with which the vector difference should be computed.
256 * \return A reference to this three-dimensional vector.
257 */
258 inline Vector3 &operator-=(const Vector3 &vector)
259 {
260 val_[0] -= vector[0];
261 val_[1] -= vector[1];
262 val_[2] -= vector[2];
263
264 return *this;
265 }
266
267 inline Vector3 &operator=(const Vector3 &vector)
268 {
269 val_[0] = vector[0];
270 val_[1] = vector[1];
271 val_[2] = vector[2];
272
273 return *this;
274 }
275
276 private:
277 float val_[3];
278 };
279
280
281 /**
282 * \relates Vector3
283 * \brief Computes the scalar multiplication of the specified three-dimensional vector with the specified scalar value.
284 * \param scalar The scalar value with which the scalar multiplication should be computed.
285 * \param vector The three-dimensional vector with which the scalar multiplication should be computed.
286 * \return The scalar multiplication of the three-dimensional vector with the scalar value.
287 */
288 inline Vector3 operator*(float scalar, const Vector3 &vector)
289 {
290 return Vector3(scalar * vector[0], scalar * vector[1], scalar * vector[2]);
291 }
292
293 /**
294 * \relates Vector3
295 * \brief Computes the cross product of the specified three-dimensional vectors.
296 * \param vector1 The first vector with which the cross product should be computed.
297 * \param vector2 The second vector with which the cross product should be computed.
298 * \return The cross product of the two specified vectors.
299 */
300 inline Vector3 cross(const Vector3 &vector1, const Vector3 &vector2)
301 {
302 return Vector3(vector1[1] * vector2[2] - vector1[2] * vector2[1], vector1[2] * vector2[0] - vector1[0] * vector2[2], vector1[0] * vector2[1] - vector1[1] * vector2[0]);
303 }
304
305 /**
306 * \relates Vector3
307 * \brief Inserts the specified three-dimensional vector into the specified output stream.
308 * \param os The output stream into which the three-dimensional vector should be inserted.
309 * \param vector The three-dimensional vector which to insert into the output stream.
310 * \return A reference to the output stream.
311 */
312 inline std::ostream &operator<<(std::ostream &os, const Vector3 &vector)
313 {
314 os << "(" << vector[0] << "," << vector[1] << "," << vector[2] << ")";
315
316 return os;
317 }
318
319 /**
320 * \relates Vector3
321 * \brief Computes the length of a specified three-dimensional vector.
322 * \param vector The three-dimensional vector whose length is to be computed.
323 * \return The length of the three-dimensional vector.
324 */
325 inline float abs(const Vector3 &vector)
326 {
327 return std::sqrt(vector * vector);
328 }
329
330 /**
331 * \relates Vector3
332 * \brief Computes the squared length of a specified three-dimensional vector.
333 * \param vector The three-dimensional vector whose squared length is to be computed.
334 * \return The squared length of the three-dimensional vector.
335 */
336 inline float absSq(const Vector3 &vector)
337 {
338 return vector * vector;
339 }
340
341 /**
342 * \relates Vector3
343 * \brief Computes the normalization of the specified three-dimensional vector.
344 * \param vector The three-dimensional vector whose normalization is to be computed.
345 * \return The normalization of the three-dimensional vector.
346 */
347 inline Vector3 normalize(const Vector3 &vector)
348 {
349 return vector / abs(vector);
350 }
351}
352
353#endif
354