LCOV - code coverage report
Current view: top level - src/utils/geom - Boundary.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 85.7 % 223 191
Test Date: 2025-11-13 15:38:19 Functions: 85.0 % 40 34

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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              : /****************************************************************************/
      14              : /// @file    Boundary.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      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              : // ===========================================================================
      35      4517622 : Boundary::Boundary()
      36      4517622 :     : myXmin(10000000000.0), myXmax(-10000000000.0),
      37      4517622 :       myYmin(10000000000.0), myYmax(-10000000000.0),
      38      4517622 :       myZmin(10000000000.0), myZmax(-10000000000.0),
      39      4517622 :       myWasInitialised(false) {}
      40              : 
      41              : 
      42       116279 : Boundary::Boundary(double x1, double y1, double x2, double y2)
      43       116279 :     : myXmin(10000000000.0), myXmax(-10000000000.0),
      44       116279 :       myYmin(10000000000.0), myYmax(-10000000000.0),
      45       116279 :       myZmin(10000000000.0), myZmax(-10000000000.0),
      46       116279 :       myWasInitialised(false) {
      47       116279 :     add(x1, y1);
      48       116279 :     add(x2, y2);
      49       116279 : }
      50              : 
      51              : 
      52            0 : Boundary::Boundary(double x1, double y1, double z1, double x2, double y2, double z2)
      53            0 :     : myXmin(10000000000.0), myXmax(-10000000000.0),
      54            0 :       myYmin(10000000000.0), myYmax(-10000000000.0),
      55            0 :       myZmin(10000000000.0), myZmax(-10000000000.0),
      56            0 :       myWasInitialised(false) {
      57            0 :     add(x1, y1, z1);
      58            0 :     add(x2, y2, z2);
      59            0 : }
      60              : 
      61              : 
      62              : void
      63         2155 : Boundary::reset() {
      64         2155 :     myXmin = 10000000000.0;
      65         2155 :     myXmax = -10000000000.0;
      66         2155 :     myYmin = 10000000000.0;
      67         2155 :     myYmax = -10000000000.0;
      68         2155 :     myZmin = 10000000000.0;
      69         2155 :     myZmax = -10000000000.0;
      70         2155 :     myWasInitialised = false;
      71         2155 : }
      72              : 
      73              : 
      74              : void
      75     12827426 : Boundary::add(double x, double y, double z) {
      76     12827426 :     if (!myWasInitialised) {
      77      3940796 :         myYmin = y;
      78      3940796 :         myYmax = y;
      79      3940796 :         myXmin = x;
      80      3940796 :         myXmax = x;
      81      3940796 :         myZmin = z;
      82      3940796 :         myZmax = z;
      83              :     } else {
      84      8886630 :         myXmin = myXmin < x ? myXmin : x;
      85      8886630 :         myXmax = myXmax > x ? myXmax : x;
      86      8886630 :         myYmin = myYmin < y ? myYmin : y;
      87      8886630 :         myYmax = myYmax > y ? myYmax : y;
      88      8886630 :         myZmin = myZmin < z ? myZmin : z;
      89      8904911 :         myZmax = myZmax > z ? myZmax : z;
      90              :     }
      91     12827426 :     myWasInitialised = true;
      92     12827426 : }
      93              : 
      94              : 
      95              : void
      96     10762021 : Boundary::add(const Position& p) {
      97     10762021 :     add(p.x(), p.y(), p.z());
      98     10762021 : }
      99              : 
     100              : 
     101              : void
     102       914978 : Boundary::add(const Boundary& p) {
     103       914978 :     add(p.xmin(), p.ymin(), p.zmin());
     104       914978 :     add(p.xmax(), p.ymax(), p.zmax());
     105       914978 : }
     106              : 
     107              : 
     108              : Position
     109       360407 : Boundary::getCenter() const {
     110       360407 :     return Position((myXmin + myXmax) / (double) 2.0, (myYmin + myYmax) / (double) 2.0, (myZmin + myZmax) / (double) 2.0);
     111              : }
     112              : 
     113              : 
     114              : double
     115      3258752 : Boundary::xmin() const {
     116      3258752 :     return myXmin;
     117              : }
     118              : 
     119              : 
     120              : double
     121      2609564 : Boundary::xmax() const {
     122      2609564 :     return myXmax;
     123              : }
     124              : 
     125              : 
     126              : double
     127      3438992 : Boundary::ymin() const {
     128      3438992 :     return myYmin;
     129              : }
     130              : 
     131              : 
     132              : double
     133      2791198 : Boundary::ymax() const {
     134      2791198 :     return myYmax;
     135              : }
     136              : 
     137              : 
     138              : double
     139       914990 : Boundary::zmin() const {
     140       914990 :     return myZmin;
     141              : }
     142              : 
     143              : 
     144              : double
     145       914990 : Boundary::zmax() const {
     146       914990 :     return myZmax;
     147              : }
     148              : 
     149              : 
     150              : double
     151     12991061 : Boundary::getWidth() const {
     152     12991061 :     return myXmax - myXmin;
     153              : }
     154              : 
     155              : 
     156              : double
     157      9337766 : Boundary::getHeight() const {
     158      9337766 :     return myYmax - myYmin;
     159              : }
     160              : 
     161              : 
     162              : double
     163         1812 : Boundary::getZRange() const {
     164         1812 :     return myZmax - myZmin;
     165              : }
     166              : 
     167              : 
     168              : bool
     169       791856 : Boundary::around(const Position& p, double offset) const {
     170              :     return
     171       401186 :         ((p.x() <= myXmax + offset) && (p.x() >= myXmin - offset)) &&
     172       802777 :         ((p.y() <= myYmax + offset) && (p.y() >= myYmin - offset)) &&
     173         2422 :         ((p.z() <= myZmax + offset) && (p.z() >= myZmin - offset));
     174              : }
     175              : 
     176              : 
     177              : bool
     178         1532 : Boundary::around2D(const Position& p, double offset) const {
     179              :     return
     180         1532 :         ((p.x() <= myXmax + offset) && (p.x() >= myXmin - offset)) &&
     181         1077 :         ((p.y() <= myYmax + offset) && (p.y() >= myYmin - offset));
     182              : }
     183              : 
     184              : 
     185              : bool
     186            0 : Boundary::around2D(const double x, const double y) const {
     187              :     return
     188            0 :         ((x <= myXmax) && (x >= myXmin)) &&
     189            0 :         ((y <= myYmax) && (y >= myYmin));
     190              : }
     191              : 
     192              : 
     193              : bool
     194       100824 : Boundary::overlapsWith(const AbstractPoly& p, double offset) const {
     195              :     if (
     196              :         // check whether one of my points lies within the given poly
     197       199533 :         partialWithin(p, offset) ||
     198              :         // check whether the polygon lies within me
     199        98709 :         p.partialWithin(*this, offset)) {
     200         2228 :         return true;
     201              :     }
     202              :     // check whether the bounderies cross
     203              :     return
     204        98596 :         p.crosses(Position(myXmax + offset, myYmax + offset), Position(myXmin - offset, myYmax + offset))
     205        98596 :         ||
     206        98596 :         p.crosses(Position(myXmin - offset, myYmax + offset), Position(myXmin - offset, myYmin - offset))
     207        98595 :         ||
     208        98595 :         p.crosses(Position(myXmin - offset, myYmin - offset), Position(myXmax + offset, myYmin - offset))
     209       197191 :         ||
     210       197191 :         p.crosses(Position(myXmax + offset, myYmin - offset), Position(myXmax + offset, myYmax + offset));
     211              : }
     212              : 
     213              : 
     214              : bool
     215       393202 : Boundary::crosses(const Position& p1, const Position& p2) const {
     216       393202 :     const PositionVector line(p1, p2);
     217              :     return
     218       393202 :         line.intersects(Position(myXmax, myYmax), Position(myXmin, myYmax))
     219       393200 :         ||
     220       393200 :         line.intersects(Position(myXmin, myYmax), Position(myXmin, myYmin))
     221       393199 :         ||
     222       393199 :         line.intersects(Position(myXmin, myYmin), Position(myXmax, myYmin))
     223       786400 :         ||
     224       786400 :         line.intersects(Position(myXmax, myYmin), Position(myXmax, myYmax));
     225       393202 : }
     226              : 
     227              : 
     228              : bool
     229            0 : Boundary::contains2D(const Boundary& b) const {
     230            0 :     if ((myXmin <= b.xmin()) && (myYmin <= b.ymin()) &&
     231            0 :             (myXmax >= b.xmax()) && (myYmax >= b.ymax())) {
     232              :         return true;
     233              :     } else {
     234            0 :         return false;
     235              :     }
     236              : }
     237              : 
     238              : 
     239              : bool
     240            0 : Boundary::overlaps2D(const Boundary& b) const {
     241            0 :     if (around2D(b.myXmin, b.myYmin)) {
     242              :         return true;
     243            0 :     } else if (around2D(b.myXmin, b.myYmax)) {
     244              :         return true;
     245            0 :     } else if (around2D(b.myXmax, b.myYmin)) {
     246              :         return true;
     247            0 :     } else if (around2D(b.myXmax, b.myYmax)) {
     248              :         return true;
     249              :     } else {
     250              :         return false;
     251              :     }
     252              : }
     253              : 
     254              : 
     255              : bool
     256          715 : Boundary::isInitialised() const {
     257          715 :     return myWasInitialised;
     258              : }
     259              : 
     260              : 
     261              : double
     262         6669 : Boundary::distanceTo2D(const Position& p) const {
     263         6669 :     const double leftDist = myXmin - p.x();
     264         6669 :     const double rightDist = p.x() - myXmax;
     265         6669 :     const double bottomDist = myYmin - p.y();
     266         6669 :     const double topDist = p.y() - myYmax;
     267         6669 :     if (leftDist > 0.) {
     268         4802 :         if (bottomDist > 0.) {
     269         3499 :             return sqrt(leftDist * leftDist + bottomDist * bottomDist);
     270              :         }
     271         1303 :         if (topDist > 0.) {
     272          503 :             return sqrt(leftDist * leftDist + topDist * topDist);
     273              :         }
     274              :         return leftDist;
     275              :     }
     276         1867 :     if (rightDist > 0.) {
     277          267 :         if (bottomDist > 0.) {
     278          187 :             return sqrt(rightDist * rightDist + bottomDist * bottomDist);
     279              :         }
     280           80 :         if (topDist > 0.) {
     281           26 :             return sqrt(rightDist * rightDist + topDist * topDist);
     282              :         }
     283              :         return rightDist;
     284              :     }
     285         1600 :     if (bottomDist > 0) {
     286              :         return bottomDist;
     287              :     }
     288          885 :     if (topDist > 0) {
     289           47 :         return topDist;
     290              :     }
     291              :     return 0.;
     292              : }
     293              : 
     294              : 
     295              : double
     296        31376 : Boundary::distanceTo2D(const Boundary& b) const {
     297        31376 :     const double leftDist = myXmin - b.myXmax;
     298        31376 :     const double rightDist = b.myXmin - myXmax;
     299        31376 :     const double bottomDist = myYmin - b.myYmax;
     300        31376 :     const double topDist = b.myYmin - myYmax;
     301        31376 :     if (leftDist > 0.) {
     302         1327 :         if (bottomDist > 0.) {
     303          212 :             return sqrt(leftDist * leftDist + bottomDist * bottomDist);
     304              :         }
     305         1115 :         if (topDist > 0.) {
     306          451 :             return sqrt(leftDist * leftDist + topDist * topDist);
     307              :         }
     308              :         return leftDist;
     309              :     }
     310        30049 :     if (rightDist > 0.) {
     311        13521 :         if (bottomDist > 0.) {
     312          264 :             return sqrt(rightDist * rightDist + bottomDist * bottomDist);
     313              :         }
     314        13257 :         if (topDist > 0.) {
     315         7871 :             return sqrt(rightDist * rightDist + topDist * topDist);
     316              :         }
     317              :         return rightDist;
     318              :     }
     319        16528 :     if (bottomDist > 0) {
     320              :         return bottomDist;
     321              :     }
     322        15329 :     if (topDist > 0) {
     323         3531 :         return topDist;
     324              :     }
     325              :     return 0.;
     326              : }
     327              : 
     328              : 
     329              : bool
     330       199239 : Boundary::partialWithin(const AbstractPoly& poly, double offset) const {
     331              :     return
     332       396858 :         poly.around(Position(myXmax, myYmax), offset) ||
     333       394941 :         poly.around(Position(myXmin, myYmax), offset) ||
     334       593666 :         poly.around(Position(myXmax, myYmin), offset) ||
     335       197105 :         poly.around(Position(myXmin, myYmin), offset);
     336              : }
     337              : 
     338              : 
     339              : Boundary&
     340      1118344 : Boundary::grow(double by) {
     341              : 
     342      1118344 :     myXmax += by;
     343      1118344 :     myYmax += by;
     344      1118344 :     myXmin -= by;
     345      1118344 :     myYmin -= by;
     346      1118344 :     return *this;
     347              : }
     348              : 
     349              : 
     350              : Boundary&
     351            0 : Boundary::scale(double by) {
     352            0 :     growWidth(by * (myXmax - myXmin));
     353            0 :     growHeight(by * (myYmax - myYmin));
     354            0 :     return *this;
     355              : }
     356              : 
     357              : 
     358              : void
     359      2238349 : Boundary::growWidth(double by) {
     360      2238349 :     myXmin -= by;
     361      2238349 :     myXmax += by;
     362      2238349 : }
     363              : 
     364              : 
     365              : void
     366      1383911 : Boundary::growHeight(double by) {
     367      1383911 :     myYmin -= by;
     368      1383911 :     myYmax += by;
     369      1383911 : }
     370              : 
     371              : void
     372           24 : Boundary::flipY() {
     373           24 :     myYmin *= -1.0;
     374           24 :     myYmax *= -1.0;
     375              :     double tmp = myYmin;
     376           24 :     myYmin = myYmax;
     377           24 :     myYmax = tmp;
     378           24 : }
     379              : 
     380              : 
     381              : 
     382              : std::ostream&
     383         7496 : operator<<(std::ostream& os, const Boundary& b) {
     384        29984 :     os << b.myXmin << "," << b.myYmin << "," << b.myXmax << "," << b.myYmax;
     385         7496 :     return os;
     386              : }
     387              : 
     388              : 
     389              : bool
     390          370 : Boundary::operator==(const Boundary& b) const {
     391              :     return (
     392          370 :                myXmin == b.myXmin &&
     393            0 :                myXmax == b.myXmax &&
     394            0 :                myYmin == b.myYmin &&
     395            0 :                myYmax == b.myYmax &&
     396            0 :                myZmin == b.myZmin &&
     397          370 :                myZmax == b.myZmax &&
     398            0 :                myWasInitialised == b.myWasInitialised);
     399              : }
     400              : 
     401              : 
     402              : bool
     403            0 : Boundary::operator!=(const Boundary& b) const {
     404            0 :     return !(*this == b);
     405              : }
     406              : 
     407              : 
     408              : void
     409          436 : Boundary::set(double xmin, double ymin, double xmax, double ymax) {
     410              :     /*
     411              :         Takes care of the following extraneous cases w.r.t the input parameters:
     412              :             - xmin > xmax
     413              :             - ymin > ymax
     414              :     */
     415              : 
     416          436 :     myXmin = MIN2(xmin, xmax);
     417          436 :     myYmin = MIN2(ymin, ymax);
     418          436 :     myXmax = MAX2(xmin, xmax);
     419          436 :     myYmax = MAX2(ymin, ymax);
     420          436 : }
     421              : 
     422              : 
     423              : void
     424            2 : Boundary::setOffsets(double xmin, double ymin, double xmax, double ymax) {
     425            2 :     myXmin = xmin;
     426            2 :     myYmin = ymin;
     427            2 :     myXmax = xmax;
     428            2 :     myYmax = ymax;
     429            2 : }
     430              : 
     431              : 
     432              : void
     433         1435 : Boundary::moveby(double x, double y, double z) {
     434         1435 :     myXmin += x;
     435         1435 :     myYmin += y;
     436         1435 :     myZmin += z;
     437         1435 :     myXmax += x;
     438         1435 :     myYmax += y;
     439         1435 :     myZmax += z;
     440         1435 : }
     441              : 
     442              : 
     443              : PositionVector
     444         2290 : Boundary::getShape(const bool closeShape) const {
     445         2290 :     PositionVector shape;
     446         2290 :     shape.push_back(Position(myXmin, myYmin));
     447         2290 :     shape.push_back(Position(myXmin, myYmax));
     448         2290 :     shape.push_back(Position(myXmax, myYmax));
     449         2290 :     shape.push_back(Position(myXmax, myYmin));
     450         2290 :     if (closeShape) {
     451         2290 :         shape.push_back(Position(myXmin, myYmin));
     452              :     }
     453         2290 :     return shape;
     454            0 : }
     455              : 
     456              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1