BoundingBox2-Impl.h
Go to the documentation of this file.
1 /*************************************************************************
2 > File Name: BoundingBox2-Impl.h
3 > Project Name: CubbyFlow
4 > Author: Dongmin Kim
5 > Purpose: 2-D axis-aligned bounding box class.
6 > Created Time: 2017/03/31
7 > Copyright (c) 2018, Dongmin Kim
8 *************************************************************************/
9 #ifndef CUBBYFLOW_BOUNDING_BOX2_IMPL_H
10 #define CUBBYFLOW_BOUNDING_BOX2_IMPL_H
11 
12 namespace CubbyFlow
13 {
14  template <typename T>
16  {
17  Reset();
18  }
19 
20  template <typename T>
22  {
23  lowerCorner.x = std::min(point1.x, point2.x);
24  lowerCorner.y = std::min(point1.y, point2.y);
25  upperCorner.x = std::max(point1.x, point2.x);
26  upperCorner.y = std::max(point1.y, point2.y);
27  }
28 
29  template <typename T>
31  lowerCorner(other.lowerCorner), upperCorner(other.upperCorner)
32  {
33  // Do nothing
34  }
35 
36  template <typename T>
38  {
39  return upperCorner.x - lowerCorner.x;
40  }
41 
42  template <typename T>
44  {
45  return upperCorner.y - lowerCorner.y;
46  }
47 
48  template <typename T>
50  {
51  return upperCorner[axis] - lowerCorner[axis];
52  }
53 
54  template <typename T>
55  bool BoundingBox<T, 2>::Overlaps(const BoundingBox& other) const
56  {
57  if (upperCorner.x < other.lowerCorner.x || lowerCorner.x > other.upperCorner.x)
58  {
59  return false;
60  }
61 
62  if (upperCorner.y < other.lowerCorner.y || lowerCorner.y > other.upperCorner.y)
63  {
64  return false;
65  }
66 
67  return true;
68  }
69 
70  template <typename T>
71  bool BoundingBox<T, 2>::Contains(const Vector2<T>& point) const
72  {
73  if (upperCorner.x < point.x || lowerCorner.x > point.x)
74  {
75  return false;
76  }
77 
78  if (upperCorner.y < point.y || lowerCorner.y > point.y)
79  {
80  return false;
81  }
82 
83  return true;
84  }
85 
86  template <typename T>
87  bool BoundingBox<T, 2>::Intersects(const Ray2<T>& ray) const
88  {
89  T min = 0;
90  T max = std::numeric_limits<T>::max();
91 
92  const Vector2<T>& rayInvDir = ray.direction.RDiv(1);
93 
94  for (size_t i = 0; i < 2; ++i)
95  {
96  T near = (lowerCorner[i] - ray.origin[i]) * rayInvDir[i];
97  T far = (upperCorner[i] - ray.origin[i]) * rayInvDir[i];
98 
99  if (near > far)
100  {
101  std::swap(near, far);
102  }
103 
104  min = std::max(near, min);
105  max = std::min(far, max);
106 
107  if (min > max)
108  {
109  return false;
110  }
111  }
112 
113  return true;
114  }
115 
116  template <typename T>
118  {
119  BoundingBoxRayIntersection2<T> intersection;
120 
121  T min = 0;
122  T max = std::numeric_limits<T>::max();
123 
124  const Vector2<T>& rayInvDir = ray.direction.RDiv(1);
125 
126  for (size_t i = 0; i < 2; ++i)
127  {
128  T near = (lowerCorner[i] - ray.origin[i]) * rayInvDir[i];
129  T far = (upperCorner[i] - ray.origin[i]) * rayInvDir[i];
130 
131  if (near > far)
132  {
133  std::swap(near, far);
134  }
135 
136  min = std::max(near, min);
137  max = std::min(far, max);
138 
139  if (min > max)
140  {
141  intersection.isIntersecting = false;
142  return intersection;
143  }
144  }
145 
146  intersection.isIntersecting = true;
147 
148  if (Contains(ray.origin))
149  {
150  intersection.near = max;
151  intersection.far = std::numeric_limits<T>::max();
152  }
153  else
154  {
155  intersection.near = min;
156  intersection.far = max;
157  }
158 
159  return intersection;
160  }
161 
162  template <typename T>
164  {
165  return (upperCorner + lowerCorner) / static_cast<T>(2);
166  }
167 
168  template <typename T>
170  {
171  return (upperCorner - lowerCorner).Length();
172  }
173 
174  template <typename T>
176  {
177  return (upperCorner - lowerCorner).LengthSquared();
178  }
179 
180  template <typename T>
182  {
183  lowerCorner.x = std::numeric_limits<T>::max();
184  lowerCorner.y = std::numeric_limits<T>::max();
185  upperCorner.x = -std::numeric_limits<T>::max();
186  upperCorner.y = -std::numeric_limits<T>::max();
187  }
188 
189  template <typename T>
191  {
192  lowerCorner.x = std::min(lowerCorner.x, point.x);
193  lowerCorner.y = std::min(lowerCorner.y, point.y);
194  upperCorner.x = std::max(upperCorner.x, point.x);
195  upperCorner.y = std::max(upperCorner.y, point.y);
196  }
197 
198  template <typename T>
200  {
201  lowerCorner.x = std::min(lowerCorner.x, other.lowerCorner.x);
202  lowerCorner.y = std::min(lowerCorner.y, other.lowerCorner.y);
203  upperCorner.x = std::max(upperCorner.x, other.upperCorner.x);
204  upperCorner.y = std::max(upperCorner.y, other.upperCorner.y);
205  }
206 
207  template <typename T>
209  {
210  lowerCorner -= delta;
211  upperCorner += delta;
212  }
213 
214  template <typename T>
216  {
217  static const T h = static_cast<T>(1) / 2;
218  static const Vector2<T> offset[4] =
219  {
220  { -h, -h }, { +h, -h }, { -h, +h }, { +h, +h }
221  };
222 
223  return Vector2<T>(GetWidth(), GetHeight()) * offset[idx] + MidPoint();
224  }
225 
226  template <typename T>
228  {
230  }
231 
232  template <typename T>
234  {
235  return (lowerCorner.x >= upperCorner.x || lowerCorner.y >= upperCorner.y);
236  }
237 }
238 
239 #endif
VectorType upperCorner
Upper corner of the bounding box.
Definition: BoundingBox.h:34
T x
X (or the first) component of the vector.
Definition: Vector2.h:29
bool Contains(const VectorType &point) const
Returns true if the input point is inside of this box.
Definition: BoundingBox-Impl.h:54
T far
Distance to the second (and the last) intersection point.
Definition: BoundingBox2.h:35
VectorType MidPoint() const
Returns the mid-point of this box.
Definition: BoundingBox-Impl.h:68
BoundingBox()
Default constructor.
Definition: BoundingBox-Impl.h:17
Generic N-D axis-aligned bounding box class.
Definition: BoundingBox.h:23
Class for 2-D ray.
Definition: Ray2.h:23
Vector2< T > origin
The origin of the ray.
Definition: Ray2.h:26
Vector2< T > direction
The direction of the ray.
Definition: Ray2.h:32
void Reset()
Resets this box to initial state (min=infinite, max=-infinite).
Definition: BoundingBox-Impl.h:107
T near
Distance to the first intersection point.
Definition: BoundingBox2.h:32
Definition: pybind11Utils.h:24
bool isIntersecting
True if the box and ray intersects.
Definition: BoundingBox2.h:29
T Clamp(T val, T low, T high)
Returns the clamped value.
Definition: MathUtils-Impl.h:123
VectorType lowerCorner
Lower corner of the bounding box.
Definition: BoundingBox.h:31
2-D box-ray intersection result.
Definition: BoundingBox2.h:26
T y
Y (or the second) component of the vector.
Definition: Vector2.h:35
T DiagonalLength() const
Returns diagonal length of this box.
Definition: BoundingBox-Impl.h:81
void Merge(const VectorType &point)
Merges this and other point.
Definition: BoundingBox-Impl.h:117
2-D vector class.
Definition: Vector2.h:26
bool Overlaps(const BoundingBox &other) const
Returns true of this box and other box overlaps.
Definition: BoundingBox-Impl.h:40
void Expand(T delta)
Definition: BoundingBox-Impl.h:137
T DiagonalLengthSquared() const
Returns squared diagonal length of this box.
Definition: BoundingBox-Impl.h:94