Line | Branch | Exec | Source |
---|---|---|---|
1 | // SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH | ||
2 | // | ||
3 | // SPDX-License-Identifier: MIT | ||
4 | |||
5 | #pragma once | ||
6 | |||
7 | #include <cstdint> | ||
8 | #include <stdexcept> | ||
9 | #include <cmath> | ||
10 | #include <iomanip> | ||
11 | #include <sstream> | ||
12 | |||
13 | namespace imgdoc2 | ||
14 | { | ||
15 | /// This defines the time for a primary key, used to uniquely identify a record in a table. | ||
16 | typedef std::int64_t dbIndex; | ||
17 | |||
18 | /// Defines an alias representing the "dimension". Legal dimensions are a-z and A-Z. Use IsDimensionValid(Dimension) to check for a legal dimension value. | ||
19 | typedef char Dimension; | ||
20 | |||
21 | /// Queries if the specified value is a legal dimension. Legal dimensions are a-z and A-Z. | ||
22 | /// \param dimension The dimension. | ||
23 | /// \returns True if the dimension is valid, false if not. | ||
24 | 340 | inline bool IsDimensionValid(Dimension dimension) | |
25 | { | ||
26 |
7/8✓ Branch 0 taken 142 times.
✓ Branch 1 taken 198 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 138 times.
✓ Branch 4 taken 202 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 198 times.
✓ Branch 7 taken 4 times.
|
340 | return ((dimension >= 'a' && dimension <= 'z') || (dimension >= 'A' && dimension <= 'Z')); |
27 | } | ||
28 | |||
29 | /// Throw an invalid_argument exception if the specified dimension is invalid. | ||
30 | /// \exception std::invalid_argument Thrown when an invalid argument error condition occurs. | ||
31 | /// \param dimension The dimension. | ||
32 | 334 | inline void ThrowIfDimensionInvalid(Dimension dimension) | |
33 | { | ||
34 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 332 times.
|
334 | if (!imgdoc2::IsDimensionValid(dimension)) |
35 | { | ||
36 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | std::ostringstream ss; |
37 |
8/16✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 2 times.
✗ Branch 25 not taken.
|
2 | ss << "The character '" << (isprint(dimension) ? dimension : '?') << "'=0x" << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(dimension) << " is not a valid dimension specifier."; |
38 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | throw std::invalid_argument(ss.str()); |
39 | 2 | } | |
40 | 332 | } | |
41 | |||
42 | /// Structure defining a point in two dimensions. | ||
43 | /// \tparam t Generic type parameter. | ||
44 | template <typename t> | ||
45 | struct PointT | ||
46 | { | ||
47 | /// Default constructor which sets all properties to zero. | ||
48 | PointT() :x(0), y(0) {} | ||
49 | |||
50 | /// Constructor | ||
51 | /// \param x The x-coordinate of the point. | ||
52 | /// \param y The y-coordinate of the point. | ||
53 | 16 | PointT(t x, t y) :x(x), y(y) {} | |
54 | |||
55 | t x; ///< The x-coordinate of the point. | ||
56 | t y; ///< The y-coordinate of the point. | ||
57 | }; | ||
58 | |||
59 | /// Structure defining a point in two dimensions with floats representing the coordinates. | ||
60 | struct PointF : PointT<float> | ||
61 | { | ||
62 | /// Default constructor which sets all properties to zero. | ||
63 | PointF() :PointT<float>() {} | ||
64 | |||
65 | /// Constructor | ||
66 | /// \param x The x-coordinate of the point. | ||
67 | /// \param y The y-coordinate of the point. | ||
68 | 4 | PointF(float x, float y) :PointT<float>(x, y) {} | |
69 | }; | ||
70 | |||
71 | /// Structure defining a point in two dimensions with doubles representing the coordinates. | ||
72 | struct PointD : PointT<double> | ||
73 | { | ||
74 | /// Default constructor which sets all properties to zero. | ||
75 | PointD() :PointT<double>() {} | ||
76 | |||
77 | /// Constructor | ||
78 | /// \param x The x-coordinate of the point. | ||
79 | /// \param y The y-coordinate of the point. | ||
80 | 4 | PointD(double x, double y) :PointT<double>(x, y) {} | |
81 | }; | ||
82 | |||
83 | /// Structure defining a point in three dimensions. | ||
84 | /// \tparam t Generic type parameter. | ||
85 | template <typename t> | ||
86 | struct Point3dT | ||
87 | { | ||
88 | /// Default constructor which sets all properties to zero. | ||
89 | Point3dT() :x(0), y(0), z(0) {} | ||
90 | |||
91 | /// Constructor | ||
92 | /// \param x The x-coordinate of the point. | ||
93 | /// \param y The y-coordinate of the point. | ||
94 | /// \param z The z-coordinate of the point. | ||
95 | 8564 | Point3dT(t x, t y, t z) :x(x), y(y), z(z) {} | |
96 | |||
97 | t x; ///< The x-coordinate of the point. | ||
98 | t y; ///< The y-coordinate of the point. | ||
99 | t z; ///< The z-coordinate of the point. | ||
100 | }; | ||
101 | |||
102 | /// Structure defining a point in three dimensions with floats representing the coordinates. | ||
103 | struct Point3dF : Point3dT<float> | ||
104 | { | ||
105 | Point3dF() :Point3dT<float>() {} | ||
106 | |||
107 | /// Constructor. | ||
108 | /// \param x The x coordinate. | ||
109 | /// \param y The y coordinate. | ||
110 | /// \param z The z coordinate. | ||
111 | 4 | Point3dF(float x, float y, float z) :Point3dT<float>(x, y, z) {} | |
112 | }; | ||
113 | |||
114 | /// Structure defining a point in three dimensions with doubles representing the coordinates. | ||
115 | struct Point3dD : Point3dT<double> | ||
116 | { | ||
117 | Point3dD() :Point3dT<double>() {} | ||
118 | |||
119 | /// Constructor. | ||
120 | /// \param x The x coordinate. | ||
121 | /// \param y The y coordinate. | ||
122 | /// \param z The z coordinate. | ||
123 | 88 | Point3dD(double x, double y, double z) :Point3dT<double>(x, y, z) {} | |
124 | }; | ||
125 | |||
126 | /// Structure defining an axis-aligned rectangle in two dimensions. | ||
127 | /// \tparam t Generic type parameter. | ||
128 | template<typename t> | ||
129 | struct RectangleT | ||
130 | { | ||
131 | /// Default constructor which sets all properties to zero. | ||
132 | RectangleT() :x(0), y(0), w(0), h(0) {} | ||
133 | |||
134 | /// Constructor | ||
135 | /// \exception std::invalid_argument Thrown when an invalid argument error condition occurs. | ||
136 | /// \param x The x-coordinate of the edge point of the rectangle. | ||
137 | /// \param y The y-coordinate of the edge point of the rectangle. | ||
138 | /// \param w The width of the rectangle. | ||
139 | /// \param h The height of the rectangle. | ||
140 | 24 | RectangleT(t x, t y, t w, t h) | |
141 | { | ||
142 |
3/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
24 | if (w < 0 || h < 0) |
143 | { | ||
144 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
6 | throw std::invalid_argument("width and height must be non-negative"); |
145 | } | ||
146 | |||
147 | 18 | this->x = x; | |
148 | 18 | this->y = y; | |
149 | 18 | this->w = w; | |
150 | 18 | this->h = h; | |
151 | 18 | } | |
152 | |||
153 | t x; ///< The x-coordinate of the edge point of the rectangle. | ||
154 | t y; ///< The y-coordinate of the edge point of the rectangle. | ||
155 | t w; ///< The width of the rectangle. | ||
156 | t h; ///< The height of the rectangle. | ||
157 | |||
158 | /// Query if the specified point 'p' is inside the rectangle. | ||
159 | /// \param p The point to test. | ||
160 | /// \returns True if point inside, false if not. | ||
161 | 16 | inline bool IsPointInside(const PointT<t>& p) const | |
162 | { | ||
163 |
5/8✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
|
16 | if (this->x <= p.x && (this->x + this->w) >= p.x && this->y <= p.y && (this->y + this->h) >= p.y) |
164 | { | ||
165 | 8 | return true; | |
166 | } | ||
167 | |||
168 | 8 | return false; | |
169 | } | ||
170 | }; | ||
171 | |||
172 | /// Structure defining an axis-aligned rectangle in two dimensions with floats representing the coordinates. | ||
173 | struct RectangleF : RectangleT<float> | ||
174 | { | ||
175 | RectangleF() :RectangleT<float>() {} | ||
176 | |||
177 | // Constructor. | ||
178 | /// \exception std::invalid_argument Thrown when an invalid argument error condition occurs. | ||
179 | /// \param x The x-coordinate of the edge point of the rectangle. | ||
180 | /// \param y The y-coordinate of the edge point of the rectangle. | ||
181 | /// \param w The width of the rectangle. | ||
182 | /// \param h The height of the rectangle. | ||
183 | 4 | RectangleF(float x, float y, float w, float h) :RectangleT<float>(x, y, w, h) {} | |
184 | }; | ||
185 | |||
186 | /// Structure defining an axis-aligned rectangle in two dimensions with doubles representing the coordinates. | ||
187 | struct RectangleD : RectangleT<double> | ||
188 | { | ||
189 | RectangleD() :RectangleT<double>() {} | ||
190 | |||
191 | // Constructor. | ||
192 | /// \exception std::invalid_argument Thrown when an invalid argument error condition occurs. | ||
193 | /// \param x The x-coordinate of the edge point of the rectangle. | ||
194 | /// \param y The y-coordinate of the edge point of the rectangle. | ||
195 | /// \param w The width of the rectangle. | ||
196 | /// \param h The height of the rectangle. | ||
197 | 16 | RectangleD(double x, double y, double w, double h) :RectangleT<double>(x, y, w, h) {} | |
198 | }; | ||
199 | |||
200 | /// This structure defines a line in two dimensions by specifying two points on this line. | ||
201 | /// Coordinates are represented by floats. | ||
202 | struct LineThruTwoPointsF | ||
203 | { | ||
204 | PointF a; ///< The first point on the line. | ||
205 | PointF b; ///< The second point on the line. | ||
206 | }; | ||
207 | |||
208 | /// This structure defines a line in two dimensions by specifying two points on this line. | ||
209 | /// Coordinates are represented by doubles. | ||
210 | struct LineThruTwoPointsD | ||
211 | { | ||
212 | PointD a; ///< The first point on the line. | ||
213 | PointD b; ///< The second point on the line. | ||
214 | }; | ||
215 | |||
216 | template <typename t> struct Vector3dT; | ||
217 | template<typename T> struct Plane_NormalAndDist; | ||
218 | |||
219 | /// Structure defining an axis-aligned cuboid in three dimensions. | ||
220 | /// \tparam t Generic type parameter. | ||
221 | template<typename t> | ||
222 | struct CuboidT | ||
223 | { | ||
224 | /// Default constructor. All properties are set to zero. | ||
225 | CuboidT() :x(0), y(0), z(0), w(0), h(0), d(0) {} | ||
226 | |||
227 | /// Constructor. | ||
228 | /// \exception std::invalid_argument Thrown when an invalid argument error condition occurs. | ||
229 | /// \param x The x-coordinate of the edge point of the cuboid. | ||
230 | /// \param y The y-coordinate of the edge point of the cuboid. | ||
231 | /// \param z The z-coordinate of the edge point of the cuboid. | ||
232 | /// \param w The width of the cuboid (i.e. the extent in x-direction). | ||
233 | /// \param h The height of the cuboid (i.e. the extent in y-direction). | ||
234 | /// \param d The depth of the cuboid (i.e. the extent in z-direction). | ||
235 | 8488 | CuboidT(t x, t y, t z, t w, t h, t d) | |
236 | { | ||
237 |
4/6✓ Branch 0 taken 8484 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8480 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8480 times.
|
8488 | if (w < 0 || h < 0 || d < 0) |
238 | { | ||
239 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
6 | throw std::invalid_argument("width and height must be non-negative"); |
240 | } | ||
241 | |||
242 | 8482 | this->x = x; | |
243 | 8482 | this->y = y; | |
244 | 8482 | this->z = z; | |
245 | 8482 | this->w = w; | |
246 | 8482 | this->h = h; | |
247 | 8482 | this->d = d; | |
248 | 8482 | } | |
249 | |||
250 | t x; ///< The x-coordinate of the edge point of the cuboid. | ||
251 | t y; ///< The y-coordinate of the edge point of the cuboid. | ||
252 | t z; ///< The z-coordinate of the edge point of the cuboid. | ||
253 | t w; ///< The width of the cuboid (i.e. the extent in x-direction). | ||
254 | t h; ///< The height of the cuboid (i.e. the extent in y-direction). | ||
255 | t d; ///< The depth of the cuboid (i.e. the extent in z-direction). | ||
256 | |||
257 | /// Query if the specified point 'p' is inside the cubiod. | ||
258 | /// \param p The point to test. | ||
259 | /// \returns True if point inside, false if not. | ||
260 | 16 | bool IsPointInside(const Point3dT<t>& p) const | |
261 | { | ||
262 |
7/12✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
|
16 | if (this->x <= p.x && (this->x + this->w) >= p.x && this->y <= p.y && (this->y + this->h) >= p.y && this->z <= p.z && (this->z + this->d) >= p.z) |
263 | { | ||
264 | 8 | return true; | |
265 | } | ||
266 | |||
267 | 8 | return false; | |
268 | } | ||
269 | |||
270 | /// Calculate the center point of the cuboid. | ||
271 | /// \returns The center point of the cuboid. | ||
272 | 8468 | Point3dT<t> CenterPoint() const | |
273 | { | ||
274 | 8468 | return Point3dT<t>(this->x + this->w / 2, this->y + this->h / 2, this->z + this->d / 2); | |
275 | } | ||
276 | |||
277 | /// Test whether the specified cuboid is intersecting with the specified plane. | ||
278 | /// \param aabb The axis-aligned cuboid. | ||
279 | /// \param plane The plane (given in plane-and-normal representation). | ||
280 | /// \returns True if the two objects intersect; false otherwise. | ||
281 | static bool DoIntersect(const imgdoc2::CuboidT<t>& aabb, const imgdoc2::Plane_NormalAndDist<t>& plane); | ||
282 | |||
283 | /// Test whether the specified plane is intersecting with the cuboid instance. | ||
284 | /// \param plane The plane (given in plane-and-normal representation). | ||
285 | /// \returns True if the two objects intersect; false otherwise. | ||
286 | 8468 | bool DoesIntersectWith(const imgdoc2::Plane_NormalAndDist<t>& plane) const | |
287 | { | ||
288 | 8468 | return DoIntersect(*this, plane); | |
289 | } | ||
290 | }; | ||
291 | |||
292 | /// Structure defining an axis-aligned cuboid in three dimensions with floats representing the coordinates. | ||
293 | struct CuboidF : CuboidT<float> | ||
294 | { | ||
295 | CuboidF() :CuboidT<float>() {} | ||
296 | |||
297 | /// Constructor. | ||
298 | /// \exception std::invalid_argument Thrown when an invalid argument error condition occurs. | ||
299 | /// \param x The x-coordinate of the edge point of the cuboid. | ||
300 | /// \param y The y-coordinate of the edge point of the cuboid. | ||
301 | /// \param z The z-coordinate of the edge point of the cuboid. | ||
302 | /// \param w The width of the cuboid (i.e. the extent in x-direction). | ||
303 | /// \param h The height of the cuboid (i.e. the extent in y-direction). | ||
304 | /// \param d The depth of the cuboid (i.e. the extent in z-direction). | ||
305 | 4 | CuboidF(float x, float y, float z, float w, float h, float d) :CuboidT<float>(x, y, z, w, h, d) {} | |
306 | }; | ||
307 | |||
308 | /// Structure defining an axis-aligned cuboid in three dimensions with doubles representing the coordinates. | ||
309 | struct CuboidD : CuboidT<double> | ||
310 | { | ||
311 | CuboidD() :CuboidT<double>() {} | ||
312 | |||
313 | /// Constructor. | ||
314 | /// \exception std::invalid_argument Thrown when an invalid argument error condition occurs. | ||
315 | /// \param x The x-coordinate of the edge point of the cuboid. | ||
316 | /// \param y The y-coordinate of the edge point of the cuboid. | ||
317 | /// \param z The z-coordinate of the edge point of the cuboid. | ||
318 | /// \param w The width of the cuboid (i.e. the extent in x-direction). | ||
319 | /// \param h The height of the cuboid (i.e. the extent in y-direction). | ||
320 | /// \param d The depth of the cuboid (i.e. the extent in z-direction). | ||
321 | 8480 | CuboidD(double x, double y, double z, double w, double h, double d) :CuboidT<double>(x, y, z, w, h, d) {} | |
322 | }; | ||
323 | |||
324 | /// Structure defining a vector in three dimensions. | ||
325 | /// \tparam t Generic type parameter. | ||
326 | template <typename t> | ||
327 | struct Vector3dT | ||
328 | { | ||
329 | /// Default constructor. All properties are set to zero. | ||
330 | Vector3dT() :x(0), y(0), z(0) {} | ||
331 | |||
332 | /// Constructor. | ||
333 | /// \param x The component of the vector in x-direction. | ||
334 | /// \param y The component of the vector in y-direction. | ||
335 | /// \param z The component of the vector in z-direction. | ||
336 | 17076 | Vector3dT(t x, t y, t z) :x(x), y(y), z(z) {} | |
337 | |||
338 | /// Constructor. | ||
339 | /// \param p A Point3dT<t> to convert into a vector. | ||
340 | 8496 | explicit Vector3dT(const Point3dT<t> p) : Vector3dT(p.x, p.y, p.z) {} | |
341 | |||
342 | t x; ///< The component of the vector in x-direction. | ||
343 | t y; ///< The component of the vector in y-direction. | ||
344 | t z; ///< The component of the vector in z-direction. | ||
345 | |||
346 | /// Gets a normalized vector. | ||
347 | /// \returns The normalized vector. | ||
348 | 28 | Vector3dT<t> Normalize() const | |
349 | { | ||
350 | 28 | t absVal = this->AbsoluteValue(); | |
351 | 28 | return Vector3dT(this->x / absVal, this->y / absVal, this->z / absVal); | |
352 | } | ||
353 | |||
354 | /// Calculate the squared length of the vector. | ||
355 | /// \returns The squared length of the vector. | ||
356 | 28 | t AbsoluteValueSquared() const | |
357 | { | ||
358 | 28 | return this->x * this->x + this->y * this->y + this->z * this->z; | |
359 | } | ||
360 | |||
361 | /// Calculate the length of the vector. | ||
362 | /// \returns The length of the vector. | ||
363 | 28 | t AbsoluteValue() const | |
364 | { | ||
365 | 28 | return std::sqrt(this->AbsoluteValueSquared()); | |
366 | } | ||
367 | |||
368 | /// Calculate the cross-product of two vectors. | ||
369 | /// \param vectorA The first vector. | ||
370 | /// \param vectorB The second vector. | ||
371 | /// \returns The cross-product of the two vectors. | ||
372 | 28 | static Vector3dT<t> Cross(const Vector3dT<t>& vectorA, const Vector3dT<t>& vectorB) | |
373 | { | ||
374 | return Vector3dT | ||
375 | { | ||
376 | 28 | vectorA.y * vectorB.z - vectorA.z * vectorB.y, | |
377 | 28 | vectorA.z * vectorB.x - vectorA.x * vectorB.z, | |
378 | 28 | vectorA.x * vectorB.y - vectorA.y * vectorB.x | |
379 | 28 | }; | |
380 | } | ||
381 | |||
382 | /// Calculate the dot-product of two vectors. | ||
383 | /// \param vectorA The first vector. | ||
384 | /// \param vectorB The second vector. | ||
385 | /// \returns The dot-product of the two vectors. | ||
386 | 8496 | static t Dot(const Vector3dT<t>& vectorA, const Vector3dT<t>& vectorB) | |
387 | { | ||
388 | 8496 | return vectorA.x * vectorB.x + vectorA.y * vectorB.y + vectorA.z * vectorB.z; | |
389 | } | ||
390 | }; | ||
391 | |||
392 | /// Structure defining a vector in three dimensions with floats representing the coordinates. | ||
393 | struct Vector3dF : Vector3dT<float> | ||
394 | { | ||
395 | Vector3dF() :Vector3dT<float>() {} | ||
396 | |||
397 | /// Constructor. | ||
398 | /// \param x The component of the vector in x-direction. | ||
399 | /// \param y The component of the vector in y-direction. | ||
400 | /// \param z The component of the vector in z-direction. | ||
401 | Vector3dF(float x, float y, float z) :Vector3dT<float>(x, y, z) {} | ||
402 | }; | ||
403 | |||
404 | /// Structure defining a vector in three dimensions with doubles representing the coordinates. | ||
405 | struct Vector3dD : Vector3dT<double> | ||
406 | { | ||
407 | Vector3dD() :Vector3dT<double>() {} | ||
408 | |||
409 | /// Constructor. | ||
410 | /// \param x The component of the vector in x-direction. | ||
411 | /// \param y The component of the vector in y-direction. | ||
412 | /// \param z The component of the vector in z-direction. | ||
413 | 8468 | Vector3dD(double x, double y, double z) :Vector3dT<double>(x, y, z) {} | |
414 | }; | ||
415 | |||
416 | /// Parametrization of a plane, parametrized as a normal-vector and the distance to the origin (aka "Hesse normal form"). | ||
417 | /// The normal must be normalized. | ||
418 | /// The equation of the plane is: dot( x, normal) = distance. | ||
419 | template<typename T> | ||
420 | struct Plane_NormalAndDist | ||
421 | { | ||
422 | Vector3dT<T> normal; ///< The normal of the plane. | ||
423 | T distance; ///< The distance of the plane to the origin. | ||
424 | |||
425 | /// Default constructor. All properties are initialized to zero. | ||
426 | Plane_NormalAndDist() :distance(0) {} | ||
427 | |||
428 | /// Constructor. | ||
429 | /// \param n The normal. | ||
430 | /// \param d The distance to the origin. | ||
431 | 28 | Plane_NormalAndDist(const Vector3dT<T>& n, T d) :normal(n), distance(d) {} | |
432 | |||
433 | /// Create the normal-representation of a plane for a plane defined by three points. | ||
434 | /// Precondition (not checked currently) is that the points are distinct. | ||
435 | /// \param a The first point on the plane. | ||
436 | /// \param b The second point on the plane. | ||
437 | /// \param c The third point on the plane. | ||
438 | /// \returns Normal-representation of the plane. | ||
439 | 28 | static Plane_NormalAndDist<T> FromThreePoints(Point3dT<T> a, Point3dT<T> b, Point3dT<T> c) | |
440 | { | ||
441 |
1/2✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
|
28 | const auto n = Vector3dT<T>::Cross(Vector3dT<T>(b.x - a.x, b.y - a.y, b.z - a.z), Vector3dT<T>(c.x - a.x, c.y - a.y, c.z - a.z)).Normalize(); |
442 | 28 | const auto dist = Vector3dT<T>::Dot(n, Vector3dT<T>(a)); | |
443 | 56 | return Plane_NormalAndDist<T>(n, dist); | |
444 | } | ||
445 | }; | ||
446 | |||
447 | /// Defines an alias representing a parametrization of a plane, parametrized as a normal-vector and the distance to the origin. | ||
448 | /// Coordinates are represented by floats. | ||
449 | typedef Plane_NormalAndDist<float> Plane_NormalAndDistF; | ||
450 | |||
451 | /// Defines an alias representing a parametrization of a plane, parametrized as a normal-vector and the distance to the origin. | ||
452 | /// Coordinates are represented by doubles. | ||
453 | typedef Plane_NormalAndDist<double> Plane_NormalAndDistD; | ||
454 | |||
455 | 8468 | /*static*/template<typename t> inline bool CuboidT<t>::DoIntersect(const imgdoc2::CuboidT<t>& aabb, const imgdoc2::Plane_NormalAndDist<t>& plane) | |
456 | { | ||
457 | // -> https://gdbooks.gitbooks.io/3dcollisions/content/Chapter2/static_aabb_plane.html | ||
458 | 8468 | const auto centerAabb = aabb.CenterPoint(); | |
459 |
1/2✓ Branch 1 taken 8468 times.
✗ Branch 2 not taken.
|
8468 | const Vector3dT<t> aabbExtents = Vector3dD(aabb.w / 2, aabb.h / 2, aabb.d / 2); |
460 | |||
461 | // Compute the projection interval radius of b onto L(t) = b.c + t * p.n | ||
462 | 8468 | const auto r = aabbExtents.x * fabs(plane.normal.x) + aabbExtents.y * fabs(plane.normal.y) + aabbExtents.z * fabs(plane.normal.z); | |
463 | |||
464 | // Compute distance of box center from plane | ||
465 | 8468 | const auto s = Vector3dT<t>::Dot(plane.normal, Vector3dT<t>(centerAabb)) - plane.distance; | |
466 | |||
467 | // Intersection occurs when distance s falls within [-r,+r] interval | ||
468 | 8468 | return fabs(s) <= r; | |
469 | } | ||
470 | } | ||
471 |