OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
BoundingBox.cpp
Go to the documentation of this file.
1//
2// Class BoundingBox
3//
4// This class provides functionality to compute bounding boxes, to compute if a position
5// is inside the box and to compute the intersection point between a ray and the bounding box.
6//
7// Copyright (c) 201x - 2021, Paul Scherrer Institut, Villigen PSI, Switzerland
8//
9// All rights reserved
10//
11// This file is part of OPAL.
12//
13// OPAL is free software: you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation, either version 3 of the License, or
16// (at your option) any later version.
17//
18// You should have received a copy of the GNU General Public License
19// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
20//
21#include "BoundingBox.h"
22
23#include <iomanip>
24#include <limits>
25
27 lowerLeftCorner_m(std::numeric_limits<double>::max()),
28 upperRightCorner_m(std::numeric_limits<double>::lowest())
29{}
30
31BoundingBox BoundingBox::getBoundingBox(const std::vector<Vector_t>& positions)
32{
33 BoundingBox boundingBox;
34 for (const Vector_t& position : positions) {
35 boundingBox.enlargeToContainPosition(position);
36 }
37
38 return boundingBox;
39}
40
42{
43 for (unsigned int d = 0; d < 3; ++ d) {
44 lowerLeftCorner_m[d] = std::min(lowerLeftCorner_m[d], position[d]);
46 }
47}
48
50{
51 for (unsigned int d = 0; d < 3; ++ d) {
54 }
55}
56
57boost::optional<Vector_t> BoundingBox::getIntersectionPoint(const Vector_t& position,
58 const Vector_t& direction) const
59{
60 boost::optional<Vector_t> result = boost::none;
61 double minDistance = std::numeric_limits<double>::max();
63 Vector_t normal(1, 0, 0);
64 for (unsigned int d = 0; d < 3; ++ d) {
65 double sign = -1;
66 Vector_t upperCorner = lowerLeftCorner_m + dot(normal, upperRightCorner_m) * normal;
67 for (const Vector_t& p0 : {lowerLeftCorner_m, upperCorner}) {
68 double tau = dot(p0 - position, sign * normal) / dot(direction, sign * normal);
69 if (tau < 0.0) {
70 continue;
71 }
72 Vector_t pointOnPlane = position + tau * direction;
73 Vector_t relativeP = pointOnPlane - p0;
74 bool isOnFace = true;
75 for (unsigned int i = 1; i < 3; ++ i) {
76 unsigned int idx = (d + i) % 3;
77 if (relativeP[idx] < 0 ||
78 relativeP[idx] > dimensions[idx]) {
79 isOnFace = false;
80 break;
81 }
82 }
83 if (isOnFace) {
84 double distance = euclidean_norm(pointOnPlane - position);
85 if (distance < minDistance) {
86 minDistance = distance;
87 result = pointOnPlane;
88 }
89 }
90 sign *= -1;
91 }
92
93 normal = Vector_t(normal[2], normal[0], normal[1]);
94 }
95
96 return result;
97}
98
99bool BoundingBox::isInside(const Vector_t& position) const
100{
101 Vector_t relPosition = position - lowerLeftCorner_m;
103 for (unsigned int d = 0; d < 3; ++ d) {
104 if (relPosition[d] < 0 || relPosition[d] > dimensions[d]) return false;
105 }
106 return true;
107}
108
109void BoundingBox::print(std::ostream& output) const
110{
111 int prePrecision = output.precision();
112 output << std::setprecision(8);
113 output << "Bounding box\n"
114 << "lower left corner: " << lowerLeftCorner_m << "\n"
115 << "upper right corner: " << upperRightCorner_m << std::endl;
116 output.precision(prePrecision);
117}
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
FnArg FnReal sign(a))
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void print(std::ostream &output) const
static BoundingBox getBoundingBox(const std::vector< Vector_t > &positions)
Definition: BoundingBox.cpp:31
bool isInside(const Vector_t &position) const
Definition: BoundingBox.cpp:99
Vector_t lowerLeftCorner_m
Definition: BoundingBox.h:52
Vector_t upperRightCorner_m
Definition: BoundingBox.h:53
boost::optional< Vector_t > getIntersectionPoint(const Vector_t &position, const Vector_t &direction) const
Definition: BoundingBox.cpp:57
void enlargeToContainBoundingBox(const BoundingBox &boundingBox)
Definition: BoundingBox.cpp:49
void enlargeToContainPosition(const Vector_t &position)
Definition: BoundingBox.cpp:41
int precision() const
Definition: Inform.h:112
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6