RayZaler 0.1
The free opto-mechanical simulation framework
Vector.h
1//
2// Copyright (c) 2024 Gonzalo José Carracedo Carballal
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as
6// published by the Free Software Foundation, either version 3 of the
7// License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public
15// License along with this program. If not, see
16// <http://www.gnu.org/licenses/>
17//
18
19#ifndef _VECTOR_H
20#define _VECTOR_H
21
22#include <cmath>
23#include <string>
24#include <ostream>
25#include <cstring>
26#include <complex>
27
28#define RZ_DEFAULT_COMPARE_RELATIVE_ERROR 1e-9
29#define RZ_URANDSIGN (2 * (static_cast<Real>(rand()) / RAND_MAX - .5))
30
31namespace RZ {
32 typedef double Real;
33 typedef std::complex<Real> Complex;
34
35 struct Vec3;
36 typedef Vec3 Point3;
37 static inline RZ::Vec3 operator *(RZ::Real k, RZ::Vec3 v);
38
39 static inline bool
40 isZero(Real a, Real precision = 1e-9)
41 {
42 return fabs(a) < precision;
43 }
44
45 static inline bool
46 releq(Real a, Real b, Real precision = 1e-9)
47 {
48 if (isZero(b, precision))
49 return isZero(a, precision);
50 else
51 return fabs(a - b) / fabs(b) < precision;
52 }
53
54 static inline Real
55 fabsmin(Real a, Real b)
56 {
57 return fabs(a) < fabs(b) ? a : b;
58 }
59
60 static inline Real
61 fabsmax(Real a, Real b)
62 {
63 return fabs(a) > fabs(b) ? a : b;
64 }
65
66 struct Vec3 {
67 union {
68 struct {
69 Real x, y, z;
70 };
71
72 Real coords[3];
73 };
74
75 inline Vec3() : Vec3(0, 0, 0) { }
76 inline Vec3(Real x, Real y, Real z) : x(x), y(y), z(z) { }
77 inline Vec3(const Real coords[3]) :
78 x(coords == nullptr ? 0 : coords[0]),
79 y(coords == nullptr ? 0 : coords[1]),
80 z(coords == nullptr ? 0 : coords[2]) {}
81
82 // Zero
83 static inline Vec3
84 zero()
85 {
86 return Vec3(0, 0, 0);
87 }
88
89 // Basis vectors
90 static inline Vec3
91 eX()
92 {
93 return Vec3(1, 0, 0);
94 }
95
96 // Basis vectors
97 static inline Vec3
98 eY()
99 {
100 return Vec3(0, 1, 0);
101 }
102
103 // Basis vectors
104 static inline Vec3
105 eZ()
106 {
107 return Vec3(0, 0, 1);
108 }
109
110 // Dot product
111 inline Real
112 operator * (Vec3 const &v) const
113 {
114 return x * v.x + y * v.y + z * v.z;
115 }
116
117 // Vector summation
118 inline Vec3
119 operator + (Vec3 const &v) const
120 {
121 return Vec3(x + v.x, y + v.y, z + v.z);
122 }
123
124 // Vector subtraction
125 inline Vec3
126 operator - (Vec3 const &v) const
127 {
128 return Vec3(x - v.x, y - v.y, z - v.z);
129 }
130
131 // Product by scalar
132 inline Vec3
133 operator * (Real k) const
134 {
135 return Vec3(k * x, k * y, k * z);
136 }
137
138 // Division by scalar
139 inline Vec3
140 operator / (Real k) const
141 {
142 return *this * (1. / k);
143 }
144
145 // Inline add
146 inline Vec3 &
147 operator += (const Vec3 &vec) {
148 x += vec.x;
149 y += vec.y;
150 z += vec.z;
151
152 return *this;
153 }
154
155 // Inline subtract
156 inline Vec3 &
157 operator -= (const Vec3 &vec) {
158 x -= vec.x;
159 y -= vec.y;
160 z -= vec.z;
161
162 return *this;
163 }
164
165 // Cross product
166 inline Vec3
167 cross(Vec3 const &v) const
168 {
169 return Vec3(
170 y * v.z - z * v.y,
171 z * v.x - x * v.z,
172 x * v.y - y * v.x);
173 }
174
175 // 2-norm
176 inline Real
177 norm() const
178 {
179 return sqrt(x * x + y * y + z * z);
180 }
181
182 // Normalized version
183 inline Vec3
184 normalized() const
185 {
186 Real k = 1 / norm();
187
188 return *this * k;
189 }
190
191 // Check if is null
192 inline bool
193 isNull(Real tol = 1e-9) const
194 {
195 return isZero(x, tol) && isZero(y, tol) && isZero(z, tol);
196 }
197
198 inline bool
199 compare(Vec3 const &other, Real dist) const
200 {
201 return (other - *this).norm() < dist;
202 }
203
204 inline bool
205 compare(Vec3 const &other) const
206 {
207 return this->compare(other, std::numeric_limits<Real>::epsilon());
208 }
209
210 inline bool
211 operator== (Vec3 const &other) const
212 {
213 Real norm = this->norm();
214 if (norm < std::numeric_limits<Real>::epsilon())
215 return other.norm() < std::numeric_limits<Real>::epsilon();
216
217 return (other - *this).norm() / norm < RZ_DEFAULT_COMPARE_RELATIVE_ERROR;
218 }
219
220 inline bool
221 operator!= (Vec3 const &other) const
222 {
223 return !(*this == other);
224 }
225
226 inline Vec3
227 operator-() const
228 {
229 return Vec3(-this->x, -this->y, -this->z);
230 }
231
232 inline void
233 copyToArray(Real *dest) const
234 {
235 memcpy(dest, this->coords, 3 * sizeof(Real));
236 }
237
238 inline void
239 setFromArray(const Real *coords)
240 {
241 memcpy(this->coords, coords, 3 * sizeof(Real));
242 }
243
244 std::string
245 toString() const
246 {
247 return
248 "(" + std::to_string(this->x)
249 + "," + std::to_string(this->y)
250 + "," + std::to_string(this->z)
251 + ")";
252 }
253
254 inline Vec3 &
255 operator=(RZ:: Real v)
256 {
257 coords[0] = coords[1] = coords[2] = v;
258 return *this;
259 }
260 };
261
262 static inline RZ::Vec3
263 operator *(RZ::Real k, RZ::Vec3 v)
264 {
265 return v * k;
266 }
267
268 static inline void
269 expandBox(Vec3 &p1, Vec3 &p2, Vec3 const &newPoint)
270 {
271 p1.x = fmin(p1.x, newPoint.x);
272 p1.y = fmin(p1.y, newPoint.y);
273 p1.z = fmin(p1.z, newPoint.z);
274
275 p2.x = fmax(p2.x, newPoint.x);
276 p2.y = fmax(p2.y, newPoint.y);
277 p2.z = fmax(p2.z, newPoint.z);
278 }
279}
280
281inline std::ostream&
282operator<<(std::ostream& os, const RZ::Vec3& vec)
283{
284 os << vec.toString();
285 return os;
286}
287
288#endif // _VECTOR_H
Definition: Vector.h:66