1 /*
2     Copyright (c) 2009 Andrew Caudwell (acaudwell@gmail.com)
3     All rights reserved.
4 
5     Redistribution and use in source and binary forms, with or without
6     modification, are permitted provided that the following conditions
7     are met:
8     1. Redistributions of source code must retain the above copyright
9        notice, this list of conditions and the following disclaimer.
10     2. Redistributions in binary form must reproduce the above copyright
11        notice, this list of conditions and the following disclaimer in the
12        documentation and/or other materials provided with the distribution.
13     3. The name of the author may not be used to endorse or promote products
14        derived from this software without specific prior written permission.
15 
16     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #ifndef BOUNDS_H
29 #define BOUNDS_H
30 
31 #include "display.h"
32 #include "vectors.h"
33 
34 class Bounds2D {
35 public:
36     vec2 min;
37     vec2 max;
38     bool first;
39 
centre()40     vec2 centre() const {
41         return min + (max - min) * 0.5f;
42     }
43 
width()44     float width() const {
45         return max.x - min.x;
46     }
47 
height()48     float height() const {
49         return max.y - min.y;
50     }
51 
area()52     float area() const {
53         return width() * height();
54     }
55 
reset()56     void reset() {
57         min = vec2(0.0, 0.0);
58         max = vec2(0.0, 0.0);
59         first = true;
60     }
61 
Bounds2D()62     Bounds2D() {
63         reset();
64     }
65 
Bounds2D(const vec2 & min,const vec2 & max)66     Bounds2D(const vec2& min, const vec2& max) {
67         reset();
68         update(min);
69         update(max);
70     }
71 
update(const Bounds2D & bounds)72     void update(const Bounds2D& bounds) {
73         update(bounds.min);
74         update(bounds.max);
75     }
76 
77 
set(const Bounds2D & bounds)78     void set(const Bounds2D& bounds) {
79         reset();
80         update(bounds);
81     }
82 
set(vec2 point)83     void set(vec2 point) {
84         reset();
85         update(point);
86     }
87 
set(const vec2 & a,const vec2 & b)88     void set(const vec2& a, const vec2& b) {
89         reset();
90         update(a);
91         update(b);
92     }
93 
update(const vec2 & point)94     void update(const vec2& point) {
95         if(first) {
96             min = point;
97             max = point;
98             first=false;
99             return;
100         }
101 
102         if(min.x > point.x) min.x = point.x;
103         if(min.y > point.y) min.y = point.y;
104         if(max.x < point.x) max.x = point.x;
105         if(max.y < point.y) max.y = point.y;
106     }
107 
contains(const vec2 & point)108     bool contains(const vec2& point) const {
109         if(first) return false;
110 
111         if(min.x<=point.x && min.y<=point.y && max.x >= point.x && max.y >= point.y)
112             return true;
113 
114         return false;
115     }
116 
overlaps(const Bounds2D & b)117     bool overlaps(const Bounds2D & b) const {
118 
119         if(max.y < b.min.y) return false;
120         if(min.y > b.max.y) return false;
121         if(max.x < b.min.x) return false;
122         if(min.x > b.max.x) return false;
123 
124         return true;
125     }
126 
draw()127     void draw() const{
128         glBegin(GL_LINE_STRIP);
129             glVertex2fv(glm::value_ptr(min));
130             glVertex2f(max.x, min.y);
131             glVertex2fv(glm::value_ptr(max));
132             glVertex2f(min.x, max.y);
133             glVertex2fv(glm::value_ptr(min));
134         glEnd();
135     }
136 };
137 
138 class Bounds3D {
139 public:
140     vec3 min;
141     vec3 max;
142     bool first;
143 
reset()144     void reset() {
145         min = vec3(0.0, 0.0, 0.0);
146         max = vec3(0.0, 0.0, 0.0);
147         first  = true;
148     }
149 
Bounds3D()150     Bounds3D() {
151         reset();
152     }
153 
Bounds3D(vec3 min,vec3 max)154     Bounds3D(vec3 min, vec3 max) {
155         reset();
156         update(min);
157         update(max);
158     }
159 
width()160     float width() {
161         return max.x - min.x;
162     }
163 
height()164     float height() {
165         return max.y - min.y;
166     }
167 
depth()168     float depth() {
169         return max.z - min.z;
170     }
171 
area()172     float area() {
173         return width() * height() * depth();
174     }
175 
centre()176     vec3 centre() {
177          return min + ((max-min) * 0.5f);
178     }
179 
update(vec3 point)180     void update(vec3 point) {
181         if(first) {
182             min = point;
183             max = point;
184             first = false;
185             return;
186         }
187 
188         if(min.x > point.x) min.x = point.x;
189         if(min.y > point.y) min.y = point.y;
190         if(min.z > point.z) min.z = point.z;
191         if(max.x < point.x) max.x = point.x;
192         if(max.y < point.y) max.y = point.y;
193         if(max.z < point.z) max.z = point.z;
194     }
195 
contains(vec3 & point)196     bool contains(vec3& point) {
197         if(first) return false;
198 
199         if(min.x<=point.x && min.y<=point.y && min.z<=point.z && max.x >= point.x && max.y >= point.y && max.z >= point.z)
200             return true;
201 
202         return false;
203     }
204 
draw()205     void draw() {
206         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
207         glBegin(GL_LINES);
208             glVertex3fv(glm::value_ptr(min));
209             glVertex3fv(glm::value_ptr(max));
210         glEnd();
211     }
212 
213 };
214 
215 #endif
216