All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Bounds.h
1 // Copyright eeGeo Ltd (2012-2014), All Rights Reserved
2 
3 #pragma once
4 
5 #include "VectorMath.h"
6 #include "SingleSphere.h"
7 #include <limits>
8 #include <vector>
9 
10 namespace Eegeo
11 {
12  namespace Geometry
13  {
14  class Bounds3D
15  {
16  v3 m_min;
17  v3 m_max;
18 
19  Bounds3D() {}
20 
21  public:
22  static inline Bounds3D Degenerate()
23  {
24  const float fMax = std::numeric_limits<float>::max();
25  const float fMin = -fMax;
26 
27  return Bounds3D(fMax, fMax, fMax, fMin, fMin, fMin);
28  }
29 
30  static inline Bounds3D Empty()
31  {
32  return Bounds3D(v3::Zero(), v3::Zero());
33  }
34 
35  static Bounds3D CreateFromPoints(const std::vector<v3>& points);
36 
37  static inline Bounds3D CreateFromPointPair(const v3& a, const v3& b)
38  {
39  Bounds3D bounds;
40 
41  if(a.x < b.x)
42  {
43  bounds.m_min.x = a.x;
44  bounds.m_max.x = b.x;
45  }
46  else
47  {
48  bounds.m_min.x = b.x;
49  bounds.m_max.x = a.x;
50  }
51 
52  if(a.y < b.y)
53  {
54  bounds.m_min.y = a.y;
55  bounds.m_max.y = b.y;
56  }
57  else
58  {
59  bounds.m_min.y = b.y;
60  bounds.m_max.y = a.y;
61  }
62 
63  if(a.z < b.z)
64  {
65  bounds.m_min.z = a.z;
66  bounds.m_max.z = b.z;
67  }
68  else
69  {
70  bounds.m_min.z = b.z;
71  bounds.m_max.z = a.z;
72  }
73 
74  return bounds;
75  }
76 
77  inline Bounds3D(float minX, float minY, float minZ, float maxX, float maxY, float maxZ)
78  : m_min(minX, minY, minZ)
79  , m_max(maxX, maxY, maxZ)
80  {
81  }
82 
83  Bounds3D(v3 min, v3 max)
84  : m_min(min)
85  , m_max(max)
86  {
87  }
88 
89  v3 GetMin() const { return m_min; }
90  v3 GetMax() const { return m_max; }
91 
92  v3 Center() const { return (m_min + m_max) * 0.5f; }
93 
94  void SetMinMax(v3 min, v3 max)
95  {
96  m_min = min;
97  m_max = max;
98  }
99 
100  inline void Encapsulate(const v3& vertex)
101  {
102  if(vertex.GetX() < m_min.GetX()) m_min.SetX(vertex.GetX());
103  if(vertex.GetY() < m_min.GetY()) m_min.SetY(vertex.GetY());
104  if(vertex.GetZ() < m_min.GetZ()) m_min.SetZ(vertex.GetZ());
105 
106  if(vertex.GetX() > m_max.GetX()) m_max.SetX(vertex.GetX());
107  if(vertex.GetY() > m_max.GetY()) m_max.SetY(vertex.GetY());
108  if(vertex.GetZ() > m_max.GetZ()) m_max.SetZ(vertex.GetZ());
109  }
110 
111  inline bool intersects(const Bounds3D& bounds) const
112  {
113  if(m_max.x < bounds.m_min.x || m_min.x > bounds.m_max.x) return false;
114  if(m_max.y < bounds.m_min.y || m_min.y > bounds.m_max.y) return false;
115  if(m_max.z < bounds.m_min.z || m_min.z > bounds.m_max.z) return false;
116  return true;
117  }
118 
119  bool intersectsXY(const Bounds3D& bounds) const
120  {
121  return (m_max.GetX() >= bounds.m_min.GetX()) &&
122  (m_min.GetX() <= bounds.m_max.GetX()) &&
123  (m_max.GetY() >= bounds.m_min.GetY()) &&
124  (m_min.GetY() <= bounds.m_max.GetY());
125  }
126 
127  bool intersectsSphere(const SingleSphere& sphere) const
128  {
129  float radiusSq = sphere.radius * sphere.radius;
130 
131  v3 deltaMin = sphere.centre - m_min;
132  v3 deltaMax = sphere.centre - m_max;
133 
134  if (deltaMin.x < 0.f)
135  {
136  radiusSq -= deltaMin.x*deltaMin.x;
137  }
138  else if (deltaMax.x > 0.f)
139  {
140  radiusSq -= deltaMax.x*deltaMax.x;
141  }
142 
143  if (deltaMin.y < 0.f)
144  {
145  radiusSq -= deltaMin.y*deltaMin.y;
146  }
147  else if (deltaMax.y > 0.f)
148  {
149  radiusSq -= deltaMax.y*deltaMax.y;
150  }
151 
152  if (deltaMin.z < 0.f)
153  {
154  radiusSq -= deltaMin.z*deltaMin.z;
155  }
156  else if (deltaMax.z > 0.f)
157  {
158  radiusSq -= deltaMax.z*deltaMax.z;
159  }
160 
161  return radiusSq > 0.f;
162  }
163 
164  v3 Size() const { return (m_max - m_min); };
165 
166  bool Contains(const v3& p) const
167  {
168  return (
169  p.x >= m_min.x &&
170  p.y >= m_min.y &&
171  p.z >= m_min.z &&
172  p.x <= m_max.x &&
173  p.y <= m_max.y &&
174  p.z <= m_max.z
175  );
176  }
177  };
178 
180  {
181  Eegeo::dv3 m_min;
182  Eegeo::dv3 m_max;
183 
184  public:
185  const dv3& GetMin() const
186  {
187  return m_min;
188  }
189 
190  const dv3& GetMax() const
191  {
192  return m_max;
193  }
194 
195  void SetMinMax(Eegeo::dv3 min, Eegeo::dv3 max)
196  {
197  m_min = min;
198  m_max = max;
199  }
200 
201  Eegeo::dv3 Center() const { return m_min + ((m_max - m_min)/2.0); }
202 
203  void Encapsulate(Eegeo::dv3 vertex)
204  {
205  if(vertex.GetX() < m_min.GetX()) m_min.SetX(vertex.GetX());
206  if(vertex.GetY() < m_min.GetY()) m_min.SetY(vertex.GetY());
207  if(vertex.GetZ() < m_min.GetZ()) m_min.SetZ(vertex.GetZ());
208 
209  if(vertex.GetX() > m_max.GetX()) m_max.SetX(vertex.GetX());
210  if(vertex.GetY() > m_max.GetY()) m_max.SetY(vertex.GetY());
211  if(vertex.GetZ() > m_max.GetZ()) m_max.SetZ(vertex.GetZ());
212  }
213 
214  Eegeo::dv3 Size() const { return (m_max - m_min); };
215  };
216 
217  struct Bounds2D
218  {
219  Eegeo::v2 min;
220  Eegeo::v2 max;
221 
222  static Bounds2D Degenerate()
223  {
224  return Bounds2D(
225  Eegeo::v2(std::numeric_limits<float>::max(), std::numeric_limits<float>::max()),
226  Eegeo::v2(-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max())
227  );
228  }
229 
230  static Bounds2D Empty()
231  {
232  return Bounds2D();
233  }
234 
235  Bounds2D()
236  :min(Eegeo::v2::Zero())
237  ,max(Eegeo::v2::Zero())
238  {
239  }
240 
241  Bounds2D( Eegeo::v2 min, Eegeo::v2 max):min(min), max(max)
242  {
243  }
244 
245  bool intersects(const Bounds2D& bounds) const
246  {
247  return (max.GetX() >= bounds.min.GetX()) &&
248  (min.GetX() <= bounds.max.GetX()) &&
249  (max.GetY() >= bounds.min.GetY()) &&
250  (min.GetY() <= bounds.max.GetY());
251  }
252 
253  bool contains(float x, float y) const
254  {
255  return (max.GetX() >= x) &&
256  (min.GetX() <= x) &&
257  (max.GetY() >= y) &&
258  (min.GetY() <= y);
259  }
260 
261  inline void Encapsulate(const Bounds2D& other)
262  {
263  min = v2::Min(min, other.min);
264  max = v2::Max(max, other.max);
265  }
266 
267  void addPoint(Eegeo::v2 point)
268  {
269  min = v2::Min(min, point);
270  max = v2::Max(max, point);
271  }
272 
273  void GetClockwiseVertices(v4* pVertices) const
274  {
275  pVertices[0] = v4(min.GetX(), min.GetY(), 0, 1);
276  pVertices[1] = v4(min.GetX(), max.GetY(), 0, 1);
277  pVertices[2] = v4(max.GetX(), max.GetY(), 0, 1);
278  pVertices[3] = v4(max.GetX(), min.GetY(), 0, 1);
279  }
280 
281  Eegeo::v2 center() const
282  {
283  return (min + max) * 0.5f;
284  }
285 
286  v2 Size() const
287  {
288  return max - min;
289  }
290 
291  void Translate(const v2& translation)
292  {
293  min += translation;
294  max += translation;
295  }
296  };
297  }
298 
299 }