| 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 |