SUMO - Simulation of Urban MObility
Boundary.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A class that stores the 2D geometrical boundary
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 #include <utility>
33 
34 #include "GeomHelper.h"
35 #include "Boundary.h"
36 #include "PositionVector.h"
37 #include "Position.h"
38 
39 
40 // ===========================================================================
41 // method definitions
42 // ===========================================================================
44  : myXmin(10000000000.0), myXmax(-10000000000.0),
45  myYmin(10000000000.0), myYmax(-10000000000.0),
46  myZmin(10000000000.0), myZmax(-10000000000.0),
47  myWasInitialised(false) {}
48 
49 
50 Boundary::Boundary(double x1, double y1, double x2, double y2)
51  : myXmin(10000000000.0), myXmax(-10000000000.0),
52  myYmin(10000000000.0), myYmax(-10000000000.0),
53  myZmin(10000000000.0), myZmax(-10000000000.0),
54  myWasInitialised(false) {
55  add(x1, y1);
56  add(x2, y2);
57 }
58 
59 
60 Boundary::Boundary(double x1, double y1, double z1, double x2, double y2, double z2)
61  : myXmin(10000000000.0), myXmax(-10000000000.0),
62  myYmin(10000000000.0), myYmax(-10000000000.0),
63  myZmin(10000000000.0), myZmax(-10000000000.0),
64  myWasInitialised(false) {
65  add(x1, y1, z1);
66  add(x2, y2, z2);
67 }
68 
69 
71 
72 
73 void
75  myXmin = 10000000000.0;
76  myXmax = -10000000000.0;
77  myYmin = 10000000000.0;
78  myYmax = -10000000000.0;
79  myZmin = 10000000000.0;
80  myZmax = -10000000000.0;
81  myWasInitialised = false;
82 }
83 
84 
85 void
86 Boundary::add(double x, double y, double z) {
87  if (!myWasInitialised) {
88  myYmin = y;
89  myYmax = y;
90  myXmin = x;
91  myXmax = x;
92  myZmin = z;
93  myZmax = z;
94  } else {
95  myXmin = myXmin < x ? myXmin : x;
96  myXmax = myXmax > x ? myXmax : x;
97  myYmin = myYmin < y ? myYmin : y;
98  myYmax = myYmax > y ? myYmax : y;
99  myZmin = myZmin < z ? myZmin : z;
100  myZmax = myZmax > z ? myZmax : z;
101  }
102  myWasInitialised = true;
103 }
104 
105 
106 void
108  add(p.x(), p.y(), p.z());
109 }
110 
111 
112 void
114  add(p.xmin(), p.ymin(), p.zmin());
115  add(p.xmax(), p.ymax(), p.zmax());
116 }
117 
118 
119 Position
121  return Position((myXmin + myXmax) / (double) 2.0, (myYmin + myYmax) / (double) 2.0, (myZmin + myZmax) / (double) 2.0);
122 }
123 
124 
125 double
126 Boundary::xmin() const {
127  return myXmin;
128 }
129 
130 
131 double
132 Boundary::xmax() const {
133  return myXmax;
134 }
135 
136 
137 double
138 Boundary::ymin() const {
139  return myYmin;
140 }
141 
142 
143 double
144 Boundary::ymax() const {
145  return myYmax;
146 }
147 
148 
149 double
150 Boundary::zmin() const {
151  return myZmin;
152 }
153 
154 
155 double
156 Boundary::zmax() const {
157  return myZmax;
158 }
159 
160 
161 double
163  return myXmax - myXmin;
164 }
165 
166 
167 double
169  return myYmax - myYmin;
170 }
171 
172 
173 double
175  return myZmax - myZmin;
176 }
177 
178 
179 bool
180 Boundary::around(const Position& p, double offset) const {
181  return
182  (p.x() <= myXmax + offset && p.x() >= myXmin - offset) &&
183  (p.y() <= myYmax + offset && p.y() >= myYmin - offset) &&
184  (p.z() <= myZmax + offset && p.z() >= myZmin - offset);
185 }
186 
187 
188 bool
189 Boundary::overlapsWith(const AbstractPoly& p, double offset) const {
190  if (
191  // check whether one of my points lies within the given poly
192  partialWithin(p, offset) ||
193  // check whether the polygon lies within me
194  p.partialWithin(*this, offset)) {
195  return true;
196  }
197  // check whether the bounderies cross
198  return
199  p.crosses(Position(myXmax + offset, myYmax + offset), Position(myXmin - offset, myYmax + offset))
200  ||
201  p.crosses(Position(myXmin - offset, myYmax + offset), Position(myXmin - offset, myYmin - offset))
202  ||
203  p.crosses(Position(myXmin - offset, myYmin - offset), Position(myXmax + offset, myYmin - offset))
204  ||
205  p.crosses(Position(myXmax + offset, myYmin - offset), Position(myXmax + offset, myYmax + offset));
206 }
207 
208 
209 bool
210 Boundary::crosses(const Position& p1, const Position& p2) const {
211  const PositionVector line(p1, p2);
212  return
214  ||
216  ||
218  ||
220 }
221 
222 
223 double
225  const double leftDist = myXmin - p.x();
226  const double rightDist = p.x() - myXmax;
227  const double bottomDist = myYmin - p.y();
228  const double topDist = p.y() - myYmax;
229  if (leftDist > 0.) {
230  if (bottomDist > 0.) {
231  return sqrt(leftDist * leftDist + bottomDist * bottomDist);
232  }
233  if (topDist > 0.) {
234  return sqrt(leftDist * leftDist + topDist * topDist);
235  }
236  return leftDist;
237  }
238  if (rightDist > 0.) {
239  if (bottomDist > 0.) {
240  return sqrt(rightDist * rightDist + bottomDist * bottomDist);
241  }
242  if (topDist > 0.) {
243  return sqrt(rightDist * rightDist + topDist * topDist);
244  }
245  return rightDist;
246  }
247  if (bottomDist > 0) {
248  return bottomDist;
249  }
250  if (topDist > 0) {
251  return topDist;
252  }
253  return 0.;
254 }
255 
256 
257 double
259  const double leftDist = myXmin - b.myXmax;
260  const double rightDist = b.myXmin - myXmax;
261  const double bottomDist = myYmin - b.myYmax;
262  const double topDist = b.myYmin - myYmax;
263  if (leftDist > 0.) {
264  if (bottomDist > 0.) {
265  return sqrt(leftDist * leftDist + bottomDist * bottomDist);
266  }
267  if (topDist > 0.) {
268  return sqrt(leftDist * leftDist + topDist * topDist);
269  }
270  return leftDist;
271  }
272  if (rightDist > 0.) {
273  if (bottomDist > 0.) {
274  return sqrt(rightDist * rightDist + bottomDist * bottomDist);
275  }
276  if (topDist > 0.) {
277  return sqrt(rightDist * rightDist + topDist * topDist);
278  }
279  return rightDist;
280  }
281  if (bottomDist > 0) {
282  return bottomDist;
283  }
284  if (topDist > 0) {
285  return topDist;
286  }
287  return 0.;
288 }
289 
290 
291 bool
292 Boundary::partialWithin(const AbstractPoly& poly, double offset) const {
293  return
294  poly.around(Position(myXmax, myYmax), offset) ||
295  poly.around(Position(myXmin, myYmax), offset) ||
296  poly.around(Position(myXmax, myYmin), offset) ||
297  poly.around(Position(myXmin, myYmin), offset);
298 }
299 
300 
301 Boundary&
302 Boundary::grow(double by) {
303  myXmax += by;
304  myYmax += by;
305  myXmin -= by;
306  myYmin -= by;
307  return *this;
308 }
309 
310 void
312  myXmin -= by;
313  myXmax += by;
314 }
315 
316 
317 void
319  myYmin -= by;
320  myYmax += by;
321 }
322 
323 void
325  myYmin *= -1.0;
326  myYmax *= -1.0;
327  double tmp = myYmin;
328  myYmin = myYmax;
329  myYmax = tmp;
330 }
331 
332 
333 
334 std::ostream&
335 operator<<(std::ostream& os, const Boundary& b) {
336  os << b.myXmin << "," << b.myYmin << "," << b.myXmax << "," << b.myYmax;
337  return os;
338 }
339 
340 
341 void
342 Boundary::set(double xmin, double ymin, double xmax, double ymax) {
343  myXmin = xmin;
344  myYmin = ymin;
345  myXmax = xmax;
346  myYmax = ymax;
347 }
348 
349 
350 void
351 Boundary::moveby(double x, double y, double z) {
352  myXmin += x;
353  myYmin += y;
354  myZmin += z;
355  myXmax += x;
356  myYmax += y;
357  myZmax += z;
358 }
359 
360 
361 
362 /****************************************************************************/
363 
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:132
double z() const
Returns the z-position.
Definition: Position.h:73
double zmax() const
Returns maximum z-coordinate.
Definition: Boundary.cpp:156
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:120
bool partialWithin(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary is partially within the given polygon.
Definition: Boundary.cpp:292
virtual bool around(const Position &p, double offset=0) const =0
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:144
double x() const
Returns the x-position.
Definition: Position.h:63
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
Definition: Boundary.cpp:351
double myXmax
Definition: Boundary.h:148
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.
~Boundary()
Destructor.
Definition: Boundary.cpp:70
void set(double xmin, double ymin, double xmax, double ymax)
Sets the boundary to the given values.
Definition: Boundary.cpp:342
double myZmax
Definition: Boundary.h:148
double myYmin
Definition: Boundary.h:148
double myYmax
Definition: Boundary.h:148
friend std::ostream & operator<<(std::ostream &os, const Boundary &b)
Output operator.
Definition: Boundary.cpp:335
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
double myXmin
The boundaries.
Definition: Boundary.h:148
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:162
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:168
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:189
double y() const
Returns the y-position.
Definition: Position.h:68
double myZmin
Definition: Boundary.h:148
virtual bool crosses(const Position &p1, const Position &p2) const =0
bool myWasInitialised
Information whether the boundary was initialised.
Definition: Boundary.h:151
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:302
void growHeight(double by)
Increases the height of the boundary (y-axis)
Definition: Boundary.cpp:318
bool around(const Position &p, double offset=0) const
Returns whether the boundary contains the given coordinate.
Definition: Boundary.cpp:180
void reset()
Resets the boundary.
Definition: Boundary.cpp:74
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition: Boundary.cpp:224
void flipY()
flips ymin and ymax
Definition: Boundary.cpp:324
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:126
void growWidth(double by)
Increases the width of the boundary (x-axis)
Definition: Boundary.cpp:311
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:138
virtual bool partialWithin(const AbstractPoly &poly, double offset=0) const =0
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:86
bool crosses(const Position &p1, const Position &p2) const
Returns whether the boundary crosses the given line.
Definition: Boundary.cpp:210
double getZRange() const
Returns the elevation range of the boundary (z-axis)
Definition: Boundary.cpp:174
Boundary()
Constructor - the boundary is unset.
Definition: Boundary.cpp:43
double zmin() const
Returns minimum z-coordinate.
Definition: Boundary.cpp:150