1/*!
2 * \file bounding_box.hpp
3 * \brief file bounding_box.hpp
4 *
5 * Copyright 2016 by Intel.
6 *
7 * Contact: kevin.rogovin@gmail.com
8 *
9 * This Source Code Form is subject to the
10 * terms of the Mozilla Public License, v. 2.0.
11 * If a copy of the MPL was not distributed with
12 * this file, You can obtain one at
13 * http://mozilla.org/MPL/2.0/.
14 *
15 * \author Kevin Rogovin <kevin.rogovin@gmail.com>
16 *
17 */
18
19#ifndef FASTUIDRAW_DEMO_BOUNDING_BOX_HPP
20#define FASTUIDRAW_DEMO_BOUNDING_BOX_HPP
21
22#include <fastuidraw/util/vecN.hpp>
23
24template<typename T>
25class BoundingBox
26{
27public:
28 typedef fastuidraw::vecN<T, 2> pt_type;
29
30 BoundingBox(void):
31 m_min(T(0), T(0)),
32 m_max(T(0), T(0)),
33 m_empty(true)
34 {}
35
36 BoundingBox(pt_type pmin, pt_type pmax):
37 m_min(pmin),
38 m_max(pmax),
39 m_empty(false)
40 {
41 FASTUIDRAWassert(pmin.x() <= pmax.x());
42 FASTUIDRAWassert(pmin.y() <= pmax.y());
43 }
44
45 void
46 inflated_polygon(fastuidraw::vecN<pt_type, 4> &out_data, T rad) const
47 {
48 FASTUIDRAWassert(!m_empty);
49 out_data[0] = pt_type(m_min.x() - rad, m_min.y() - rad);
50 out_data[1] = pt_type(m_max.x() + rad, m_min.y() - rad);
51 out_data[2] = pt_type(m_max.x() + rad, m_max.y() + rad);
52 out_data[3] = pt_type(m_min.x() - rad, m_max.y() + rad);
53 }
54
55 BoundingBox&
56 union_point(const pt_type &pt)
57 {
58 using namespace fastuidraw;
59 if (m_empty)
60 {
61 m_empty = false;
62 m_min = m_max = pt;
63 }
64 else
65 {
66 m_min.x() = t_min(m_min.x(), pt.x());
67 m_min.y() = t_min(m_min.y(), pt.y());
68
69 m_max.x() = t_max(m_max.x(), pt.x());
70 m_max.y() = t_max(m_max.y(), pt.y());
71 }
72 return *this;
73 }
74
75 template<typename iterator>
76 BoundingBox&
77 union_points(iterator begin, iterator end)
78 {
79 for(; begin != end; ++begin)
80 {
81 union_point(*begin);
82 }
83 return *this;
84 }
85
86 BoundingBox&
87 union_box(const BoundingBox &b)
88 {
89 if (!b.m_empty)
90 {
91 union_point(b.m_min);
92 union_point(b.m_max);
93 }
94 return *this;
95 }
96
97 pt_type
98 size(void) const
99 {
100 return m_empty ?
101 pt_type(T(0), T(0)) :
102 m_max - m_min;
103 }
104
105 bool
106 empty(void) const
107 {
108 return m_empty;
109 }
110
111 const pt_type&
112 min_point(void) const
113 {
114 return m_min;
115 }
116
117 const pt_type&
118 max_point(void) const
119 {
120 return m_max;
121 }
122
123 bool
124 intersects(const BoundingBox &v) const
125 {
126 using namespace fastuidraw;
127
128 return !m_empty && !v.m_empty
129 && t_max(m_min.x(), v.m_min.x()) <= t_min(m_max.x(), v.m_max.x())
130 && t_max(m_min.y(), v.m_min.y()) <= t_min(m_max.y(), v.m_max.y());
131 }
132
133 bool
134 intersects(const pt_type &v) const
135 {
136 using namespace fastuidraw;
137
138 return !m_empty
139 && v.x() >= m_min.x()
140 && v.x() <= m_max.x()
141 && v.y() >= m_min.y()
142 && v.y() <= m_max.y();
143 }
144
145 fastuidraw::vecN<BoundingBox, 2>
146 split(unsigned int coordinate) const
147 {
148 fastuidraw::vecN<BoundingBox, 2> R;
149 if (m_empty)
150 {
151 return R;
152 }
153
154 pt_type splitMin, splitMax;
155 T v;
156
157 v = (m_min[coordinate] + m_max[coordinate]) / T(2);
158 splitMin[coordinate] = splitMax[coordinate] = v;
159 splitMin[1 - coordinate] = m_min[1 - coordinate];
160 splitMax[1 - coordinate] = m_max[1 - coordinate];
161
162 R[0].union_point(m_min);
163 R[0].union_point(splitMax);
164
165 R[1].union_point(m_max);
166 R[1].union_point(splitMin);
167
168 return R;
169 }
170
171private:
172 pt_type m_min, m_max;
173 bool m_empty;
174};
175
176#endif
177