Eclipse SUMO - Simulation of Urban MObility
Boundary.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // A class that stores the 2D geometrical boundary
21 /****************************************************************************/
22 #include <config.h>
23 #include <utility>
24 
25 #include <utils/common/StdDefs.h>
26 #include "GeomHelper.h"
27 #include "Boundary.h"
28 #include "PositionVector.h"
29 #include "Position.h"
30 
31 
32 // ===========================================================================
33 // method definitions
34 // ===========================================================================
36  : myXmin(10000000000.0), myXmax(-10000000000.0),
37  myYmin(10000000000.0), myYmax(-10000000000.0),
38  myZmin(10000000000.0), myZmax(-10000000000.0),
39  myWasInitialised(false) {}
40 
41 
42 Boundary::Boundary(double x1, double y1, double x2, double y2)
43  : myXmin(10000000000.0), myXmax(-10000000000.0),
44  myYmin(10000000000.0), myYmax(-10000000000.0),
45  myZmin(10000000000.0), myZmax(-10000000000.0),
46  myWasInitialised(false) {
47  add(x1, y1);
48  add(x2, y2);
49 }
50 
51 
52 Boundary::Boundary(double x1, double y1, double z1, double x2, double y2, double z2)
53  : myXmin(10000000000.0), myXmax(-10000000000.0),
54  myYmin(10000000000.0), myYmax(-10000000000.0),
55  myZmin(10000000000.0), myZmax(-10000000000.0),
56  myWasInitialised(false) {
57  add(x1, y1, z1);
58  add(x2, y2, z2);
59 }
60 
61 
63 
64 
65 void
67  myXmin = 10000000000.0;
68  myXmax = -10000000000.0;
69  myYmin = 10000000000.0;
70  myYmax = -10000000000.0;
71  myZmin = 10000000000.0;
72  myZmax = -10000000000.0;
73  myWasInitialised = false;
74 }
75 
76 
77 void
78 Boundary::add(double x, double y, double z) {
79  if (!myWasInitialised) {
80  myYmin = y;
81  myYmax = y;
82  myXmin = x;
83  myXmax = x;
84  myZmin = z;
85  myZmax = z;
86  } else {
87  myXmin = myXmin < x ? myXmin : x;
88  myXmax = myXmax > x ? myXmax : x;
89  myYmin = myYmin < y ? myYmin : y;
90  myYmax = myYmax > y ? myYmax : y;
91  myZmin = myZmin < z ? myZmin : z;
92  myZmax = myZmax > z ? myZmax : z;
93  }
94  myWasInitialised = true;
95 }
96 
97 
98 void
100  add(p.x(), p.y(), p.z());
101 }
102 
103 
104 void
106  add(p.xmin(), p.ymin(), p.zmin());
107  add(p.xmax(), p.ymax(), p.zmax());
108 }
109 
110 
111 Position
113  return Position((myXmin + myXmax) / (double) 2.0, (myYmin + myYmax) / (double) 2.0, (myZmin + myZmax) / (double) 2.0);
114 }
115 
116 
117 double
118 Boundary::xmin() const {
119  return myXmin;
120 }
121 
122 
123 double
124 Boundary::xmax() const {
125  return myXmax;
126 }
127 
128 
129 double
130 Boundary::ymin() const {
131  return myYmin;
132 }
133 
134 
135 double
136 Boundary::ymax() const {
137  return myYmax;
138 }
139 
140 
141 double
142 Boundary::zmin() const {
143  return myZmin;
144 }
145 
146 
147 double
148 Boundary::zmax() const {
149  return myZmax;
150 }
151 
152 
153 double
155  return myXmax - myXmin;
156 }
157 
158 
159 double
161  return myYmax - myYmin;
162 }
163 
164 
165 double
167  return myZmax - myZmin;
168 }
169 
170 
171 bool
172 Boundary::around(const Position& p, double offset) const {
173  return
174  (p.x() <= myXmax + offset && p.x() >= myXmin - offset) &&
175  (p.y() <= myYmax + offset && p.y() >= myYmin - offset) &&
176  (p.z() <= myZmax + offset && p.z() >= myZmin - offset);
177 }
178 
179 
180 bool
181 Boundary::around2D(const Position& p, double offset) const {
182  return
183  (p.x() <= myXmax + offset && p.x() >= myXmin - offset) &&
184  (p.y() <= myYmax + offset && p.y() >= myYmin - 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
224 Boundary::contains(const Boundary& b) const {
225  if ((myXmin <= b.xmin()) && (myYmin <= b.ymin()) &&
226  (myXmax >= b.xmax()) && (myYmax >= b.ymax())) {
227  return true;
228  } else {
229  return false;
230  }
231 }
232 
233 
234 bool
236  return myWasInitialised;
237 }
238 
239 
240 double
242  const double leftDist = myXmin - p.x();
243  const double rightDist = p.x() - myXmax;
244  const double bottomDist = myYmin - p.y();
245  const double topDist = p.y() - myYmax;
246  if (leftDist > 0.) {
247  if (bottomDist > 0.) {
248  return sqrt(leftDist * leftDist + bottomDist * bottomDist);
249  }
250  if (topDist > 0.) {
251  return sqrt(leftDist * leftDist + topDist * topDist);
252  }
253  return leftDist;
254  }
255  if (rightDist > 0.) {
256  if (bottomDist > 0.) {
257  return sqrt(rightDist * rightDist + bottomDist * bottomDist);
258  }
259  if (topDist > 0.) {
260  return sqrt(rightDist * rightDist + topDist * topDist);
261  }
262  return rightDist;
263  }
264  if (bottomDist > 0) {
265  return bottomDist;
266  }
267  if (topDist > 0) {
268  return topDist;
269  }
270  return 0.;
271 }
272 
273 
274 double
276  const double leftDist = myXmin - b.myXmax;
277  const double rightDist = b.myXmin - myXmax;
278  const double bottomDist = myYmin - b.myYmax;
279  const double topDist = b.myYmin - myYmax;
280  if (leftDist > 0.) {
281  if (bottomDist > 0.) {
282  return sqrt(leftDist * leftDist + bottomDist * bottomDist);
283  }
284  if (topDist > 0.) {
285  return sqrt(leftDist * leftDist + topDist * topDist);
286  }
287  return leftDist;
288  }
289  if (rightDist > 0.) {
290  if (bottomDist > 0.) {
291  return sqrt(rightDist * rightDist + bottomDist * bottomDist);
292  }
293  if (topDist > 0.) {
294  return sqrt(rightDist * rightDist + topDist * topDist);
295  }
296  return rightDist;
297  }
298  if (bottomDist > 0) {
299  return bottomDist;
300  }
301  if (topDist > 0) {
302  return topDist;
303  }
304  return 0.;
305 }
306 
307 
308 bool
309 Boundary::partialWithin(const AbstractPoly& poly, double offset) const {
310  return
311  poly.around(Position(myXmax, myYmax), offset) ||
312  poly.around(Position(myXmin, myYmax), offset) ||
313  poly.around(Position(myXmax, myYmin), offset) ||
314  poly.around(Position(myXmin, myYmin), offset);
315 }
316 
317 
318 Boundary&
319 Boundary::grow(double by) {
320 
321  myXmax += by;
322  myYmax += by;
323  myXmin -= by;
324  myYmin -= by;
325  return *this;
326 }
327 
328 
329 Boundary&
330 Boundary::scale(double by) {
331  growWidth(by * (myXmax - myXmin));
332  growHeight(by * (myYmax - myYmin));
333  return *this;
334 }
335 
336 
337 void
339  myXmin -= by;
340  myXmax += by;
341 }
342 
343 
344 void
346  myYmin -= by;
347  myYmax += by;
348 }
349 
350 void
352  myYmin *= -1.0;
353  myYmax *= -1.0;
354  double tmp = myYmin;
355  myYmin = myYmax;
356  myYmax = tmp;
357 }
358 
359 
360 
361 std::ostream&
362 operator<<(std::ostream& os, const Boundary& b) {
363  os << b.myXmin << "," << b.myYmin << "," << b.myXmax << "," << b.myYmax;
364  return os;
365 }
366 
367 
368 bool
370  return (
371  myXmin == b.myXmin &&
372  myXmax == b.myXmax &&
373  myYmin == b.myYmin &&
374  myYmax == b.myYmax &&
375  myZmin == b.myZmin &&
376  myZmax == b.myZmax &&
378 }
379 
380 
381 bool
383  return !(*this == b);
384 }
385 
386 
387 void
388 Boundary::set(double xmin, double ymin, double xmax, double ymax) {
389  /*
390  Takes care of the following extraneous cases w.r.t the input parameters:
391  - xmin > xmax
392  - ymin > ymax
393  */
394 
395  myXmin = MIN2(xmin, xmax);
396  myYmin = MIN2(ymin, ymax);
397  myXmax = MAX2(xmin, xmax);
398  myYmax = MAX2(ymin, ymax);
399 }
400 
401 
402 void
403 Boundary::setOffsets(double xmin, double ymin, double xmax, double ymax) {
404  myXmin = xmin;
405  myYmin = ymin;
406  myXmax = xmax;
407  myYmax = ymax;
408 }
409 
410 
411 void
412 Boundary::moveby(double x, double y, double z) {
413  myXmin += x;
414  myYmin += y;
415  myZmin += z;
416  myXmax += x;
417  myYmax += y;
418  myZmax += z;
419 }
420 
421 
423 Boundary::getShape(const bool closeShape) const {
424  PositionVector shape;
425  shape.push_back(Position(myXmin, myYmin));
426  shape.push_back(Position(myXmin, myYmax));
427  shape.push_back(Position(myXmax, myYmax));
428  shape.push_back(Position(myXmax, myYmin));
429  if (closeShape) {
430  shape.push_back(Position(myXmin, myYmin));
431  }
432  return shape;
433 }
434 
435 /****************************************************************************/
std::ostream & operator<<(std::ostream &os, const Boundary &b)
Definition: Boundary.cpp:362
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
virtual bool partialWithin(const AbstractPoly &poly, double offset=0) const =0
Returns whether the AbstractPoly is partially within the given polygon.
virtual bool crosses(const Position &p1, const Position &p2) const =0
Returns whether the AbstractPoly crosses the given line.
virtual bool around(const Position &p, double offset=0) const =0
Returns whether the AbstractPoly the given coordinate.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
Position getCenter() const
Returns the center of the boundary.
Definition: Boundary.cpp:112
bool partialWithin(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary is partially within the given polygon.
Definition: Boundary.cpp:309
double myZmin
Definition: Boundary.h:169
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
void moveby(double x, double y, double z=0)
Moves the boundary by the given amount.
Definition: Boundary.cpp:412
void growHeight(double by)
Increases the height of the boundary (y-axis)
Definition: Boundary.cpp:345
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:235
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:130
double myZmax
Definition: Boundary.h:169
void reset()
Resets the boundary.
Definition: Boundary.cpp:66
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:118
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:319
void flipY()
flips ymin and ymax
Definition: Boundary.cpp:351
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition: Boundary.cpp:241
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:160
bool myWasInitialised
Information whether the boundary was initialised.
Definition: Boundary.h:172
bool overlapsWith(const AbstractPoly &poly, double offset=0) const
Returns whether the boundary overlaps with the given polygon.
Definition: Boundary.cpp:189
Boundary()
Constructor - the boundary is unset.
Definition: Boundary.cpp:35
~Boundary()
Destructor.
Definition: Boundary.cpp:62
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:154
bool operator!=(const Boundary &b) const
Comparison operator not equal.
Definition: Boundary.cpp:382
PositionVector getShape(const bool closeShape) const
get position vector (shape) based on this boundary
Definition: Boundary.cpp:423
double myYmin
Definition: Boundary.h:169
void set(double xmin, double ymin, double xmax, double ymax)
Sets the boundary to the given values.
Definition: Boundary.cpp:388
Boundary & scale(double by)
scale the boundary by the given amount
Definition: Boundary.cpp:330
double zmin() const
Returns minimum z-coordinate.
Definition: Boundary.cpp:142
bool around2D(const Position &p, double offset=0) const
Returns whether the boundary contains the given 2D coordinate.
Definition: Boundary.cpp:181
void growWidth(double by)
Increases the width of the boundary (x-axis)
Definition: Boundary.cpp:338
double myYmax
Definition: Boundary.h:169
bool crosses(const Position &p1, const Position &p2) const
Returns whether the boundary crosses the given line.
Definition: Boundary.cpp:210
bool around(const Position &p, double offset=0) const
Returns whether the boundary contains the given coordinate.
Definition: Boundary.cpp:172
void setOffsets(double xmin, double ymin, double xmax, double ymax)
Sets the boundary to the given values, ignoring min < max constraints.
Definition: Boundary.cpp:403
double contains(const Boundary &b) const
return true if this boundary contains the given boundary (only X-Y)
Definition: Boundary.cpp:224
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:136
double myXmin
The boundaries.
Definition: Boundary.h:169
double myXmax
Definition: Boundary.h:169
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:124
double zmax() const
Returns maximum z-coordinate.
Definition: Boundary.cpp:148
double getZRange() const
Returns the elevation range of the boundary (z-axis)
Definition: Boundary.cpp:166
bool operator==(const Boundary &b) const
Comparison operator equal.
Definition: Boundary.cpp:369
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double x() const
Returns the x-position.
Definition: Position.h:55
double z() const
Returns the z-position.
Definition: Position.h:65
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
bool intersects(const Position &p1, const Position &p2) const
Returns the information whether this list of points interesects the given line.