LCOV - code coverage report
Current view: top level - src/utils/geom - Boundary.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 83.5 % 224 187
Test Date: 2024-11-22 15:46:21 Functions: 81.0 % 42 34

            Line data    Source code
       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              : /****************************************************************************/
      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      4772817 : Boundary::Boundary()
      36      4772817 :     : myXmin(10000000000.0), myXmax(-10000000000.0),
      37      4772817 :       myYmin(10000000000.0), myYmax(-10000000000.0),
      38      4772817 :       myZmin(10000000000.0), myZmax(-10000000000.0),
      39      4772817 :       myWasInitialised(false) {}
      40              : 
      41              : 
      42       132704 : Boundary::Boundary(double x1, double y1, double x2, double y2)
      43       132704 :     : myXmin(10000000000.0), myXmax(-10000000000.0),
      44       132704 :       myYmin(10000000000.0), myYmax(-10000000000.0),
      45       132704 :       myZmin(10000000000.0), myZmax(-10000000000.0),
      46       132704 :       myWasInitialised(false) {
      47       132704 :     add(x1, y1);
      48       132704 :     add(x2, y2);
      49       132704 : }
      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     11281488 : Boundary::~Boundary() {}
      63              : 
      64              : 
      65              : void
      66         2032 : Boundary::reset() {
      67         2032 :     myXmin = 10000000000.0;
      68         2032 :     myXmax = -10000000000.0;
      69         2032 :     myYmin = 10000000000.0;
      70         2032 :     myYmax = -10000000000.0;
      71         2032 :     myZmin = 10000000000.0;
      72         2032 :     myZmax = -10000000000.0;
      73         2032 :     myWasInitialised = false;
      74         2032 : }
      75              : 
      76              : 
      77              : void
      78     12840146 : Boundary::add(double x, double y, double z) {
      79     12840146 :     if (!myWasInitialised) {
      80      4145280 :         myYmin = y;
      81      4145280 :         myYmax = y;
      82      4145280 :         myXmin = x;
      83      4145280 :         myXmax = x;
      84      4145280 :         myZmin = z;
      85      4145280 :         myZmax = z;
      86              :     } else {
      87      8694866 :         myXmin = myXmin < x ? myXmin : x;
      88      8694866 :         myXmax = myXmax > x ? myXmax : x;
      89      8694866 :         myYmin = myYmin < y ? myYmin : y;
      90      8694866 :         myYmax = myYmax > y ? myYmax : y;
      91      8694866 :         myZmin = myZmin < z ? myZmin : z;
      92      8711232 :         myZmax = myZmax > z ? myZmax : z;
      93              :     }
      94     12840146 :     myWasInitialised = true;
      95     12840146 : }
      96              : 
      97              : 
      98              : void
      99     10905246 : Boundary::add(const Position& p) {
     100     10905246 :     add(p.x(), p.y(), p.z());
     101     10905246 : }
     102              : 
     103              : 
     104              : void
     105       833399 : Boundary::add(const Boundary& p) {
     106       833399 :     add(p.xmin(), p.ymin(), p.zmin());
     107       833399 :     add(p.xmax(), p.ymax(), p.zmax());
     108       833399 : }
     109              : 
     110              : 
     111              : Position
     112       319838 : Boundary::getCenter() const {
     113       319838 :     return Position((myXmin + myXmax) / (double) 2.0, (myYmin + myYmax) / (double) 2.0, (myZmin + myZmax) / (double) 2.0);
     114              : }
     115              : 
     116              : 
     117              : double
     118      2918920 : Boundary::xmin() const {
     119      2918920 :     return myXmin;
     120              : }
     121              : 
     122              : 
     123              : double
     124      2378826 : Boundary::xmax() const {
     125      2378826 :     return myXmax;
     126              : }
     127              : 
     128              : 
     129              : double
     130      3080071 : Boundary::ymin() const {
     131      3080071 :     return myYmin;
     132              : }
     133              : 
     134              : 
     135              : double
     136      2540711 : Boundary::ymax() const {
     137      2540711 :     return myYmax;
     138              : }
     139              : 
     140              : 
     141              : double
     142       833404 : Boundary::zmin() const {
     143       833404 :     return myZmin;
     144              : }
     145              : 
     146              : 
     147              : double
     148       833404 : Boundary::zmax() const {
     149       833404 :     return myZmax;
     150              : }
     151              : 
     152              : 
     153              : double
     154     10809844 : Boundary::getWidth() const {
     155     10809844 :     return myXmax - myXmin;
     156              : }
     157              : 
     158              : 
     159              : double
     160      7775403 : Boundary::getHeight() const {
     161      7775403 :     return myYmax - myYmin;
     162              : }
     163              : 
     164              : 
     165              : double
     166         1694 : Boundary::getZRange() const {
     167         1694 :     return myZmax - myZmin;
     168              : }
     169              : 
     170              : 
     171              : bool
     172       792460 : Boundary::around(const Position& p, double offset) const {
     173              :     return
     174       401685 :         ((p.x() <= myXmax + offset) && (p.x() >= myXmin - offset)) &&
     175       803808 :         ((p.y() <= myYmax + offset) && (p.y() >= myYmin - offset)) &&
     176         2776 :         ((p.z() <= myZmax + offset) && (p.z() >= myZmin - offset));
     177              : }
     178              : 
     179              : 
     180              : bool
     181            0 : Boundary::around2D(const Position& p, double offset) const {
     182              :     return
     183            0 :         ((p.x() <= myXmax + offset) && (p.x() >= myXmin - offset)) &&
     184            0 :         ((p.y() <= myYmax + offset) && (p.y() >= myYmin - offset));
     185              : }
     186              : 
     187              : 
     188              : bool
     189            0 : Boundary::around2D(const double x, const double y) const {
     190              :     return
     191            0 :         ((x <= myXmax) && (x >= myXmin)) &&
     192            0 :         ((y <= myYmax) && (y >= myYmin));
     193              : }
     194              : 
     195              : 
     196              : bool
     197       100824 : Boundary::overlapsWith(const AbstractPoly& p, double offset) const {
     198              :     if (
     199              :         // check whether one of my points lies within the given poly
     200       199533 :         partialWithin(p, offset) ||
     201              :         // check whether the polygon lies within me
     202        98709 :         p.partialWithin(*this, offset)) {
     203         2228 :         return true;
     204              :     }
     205              :     // check whether the bounderies cross
     206              :     return
     207       197192 :         p.crosses(Position(myXmax + offset, myYmax + offset), Position(myXmin - offset, myYmax + offset))
     208        98596 :         ||
     209       295788 :         p.crosses(Position(myXmin - offset, myYmax + offset), Position(myXmin - offset, myYmin - offset))
     210        98595 :         ||
     211       295786 :         p.crosses(Position(myXmin - offset, myYmin - offset), Position(myXmax + offset, myYmin - offset))
     212        98596 :         ||
     213       295786 :         p.crosses(Position(myXmax + offset, myYmin - offset), Position(myXmax + offset, myYmax + offset));
     214              : }
     215              : 
     216              : 
     217              : bool
     218       393202 : Boundary::crosses(const Position& p1, const Position& p2) const {
     219       393202 :     const PositionVector line(p1, p2);
     220              :     return
     221       393202 :         line.intersects(Position(myXmax, myYmax), Position(myXmin, myYmax))
     222       393200 :         ||
     223      1179602 :         line.intersects(Position(myXmin, myYmax), Position(myXmin, myYmin))
     224       393199 :         ||
     225      1179600 :         line.intersects(Position(myXmin, myYmin), Position(myXmax, myYmin))
     226       393202 :         ||
     227      1572800 :         line.intersects(Position(myXmax, myYmin), Position(myXmax, myYmax));
     228       393202 : }
     229              : 
     230              : 
     231              : bool
     232            0 : Boundary::contains2D(const Boundary& b) const {
     233            0 :     if ((myXmin <= b.xmin()) && (myYmin <= b.ymin()) &&
     234            0 :             (myXmax >= b.xmax()) && (myYmax >= b.ymax())) {
     235              :         return true;
     236              :     } else {
     237            0 :         return false;
     238              :     }
     239              : }
     240              : 
     241              : 
     242              : bool
     243            0 : Boundary::overlaps2D(const Boundary& b) const {
     244            0 :     if (around2D(b.myXmin, b.myYmin)) {
     245              :         return true;
     246            0 :     } else if (around2D(b.myXmin, b.myYmax)) {
     247              :         return true;
     248            0 :     } else if (around2D(b.myXmax, b.myYmin)) {
     249              :         return true;
     250            0 :     } else if (around2D(b.myXmax, b.myYmax)) {
     251              :         return true;
     252              :     } else {
     253              :         return false;
     254              :     }
     255              : }
     256              : 
     257              : 
     258              : bool
     259            0 : Boundary::isInitialised() const {
     260            0 :     return myWasInitialised;
     261              : }
     262              : 
     263              : 
     264              : double
     265         6474 : Boundary::distanceTo2D(const Position& p) const {
     266         6474 :     const double leftDist = myXmin - p.x();
     267         6474 :     const double rightDist = p.x() - myXmax;
     268         6474 :     const double bottomDist = myYmin - p.y();
     269         6474 :     const double topDist = p.y() - myYmax;
     270         6474 :     if (leftDist > 0.) {
     271         4712 :         if (bottomDist > 0.) {
     272         3499 :             return sqrt(leftDist * leftDist + bottomDist * bottomDist);
     273              :         }
     274         1213 :         if (topDist > 0.) {
     275          453 :             return sqrt(leftDist * leftDist + topDist * topDist);
     276              :         }
     277              :         return leftDist;
     278              :     }
     279         1762 :     if (rightDist > 0.) {
     280          257 :         if (bottomDist > 0.) {
     281          187 :             return sqrt(rightDist * rightDist + bottomDist * bottomDist);
     282              :         }
     283           70 :         if (topDist > 0.) {
     284           26 :             return sqrt(rightDist * rightDist + topDist * topDist);
     285              :         }
     286              :         return rightDist;
     287              :     }
     288         1505 :     if (bottomDist > 0) {
     289              :         return bottomDist;
     290              :     }
     291          790 :     if (topDist > 0) {
     292           37 :         return topDist;
     293              :     }
     294              :     return 0.;
     295              : }
     296              : 
     297              : 
     298              : double
     299        29260 : Boundary::distanceTo2D(const Boundary& b) const {
     300        29260 :     const double leftDist = myXmin - b.myXmax;
     301        29260 :     const double rightDist = b.myXmin - myXmax;
     302        29260 :     const double bottomDist = myYmin - b.myYmax;
     303        29260 :     const double topDist = b.myYmin - myYmax;
     304        29260 :     if (leftDist > 0.) {
     305         1290 :         if (bottomDist > 0.) {
     306          207 :             return sqrt(leftDist * leftDist + bottomDist * bottomDist);
     307              :         }
     308         1083 :         if (topDist > 0.) {
     309          451 :             return sqrt(leftDist * leftDist + topDist * topDist);
     310              :         }
     311              :         return leftDist;
     312              :     }
     313        27970 :     if (rightDist > 0.) {
     314        13048 :         if (bottomDist > 0.) {
     315          234 :             return sqrt(rightDist * rightDist + bottomDist * bottomDist);
     316              :         }
     317        12814 :         if (topDist > 0.) {
     318         7871 :             return sqrt(rightDist * rightDist + topDist * topDist);
     319              :         }
     320              :         return rightDist;
     321              :     }
     322        14922 :     if (bottomDist > 0) {
     323              :         return bottomDist;
     324              :     }
     325        13765 :     if (topDist > 0) {
     326         3531 :         return topDist;
     327              :     }
     328              :     return 0.;
     329              : }
     330              : 
     331              : 
     332              : bool
     333       199239 : Boundary::partialWithin(const AbstractPoly& poly, double offset) const {
     334              :     return
     335       396858 :         poly.around(Position(myXmax, myYmax), offset) ||
     336       594180 :         poly.around(Position(myXmin, myYmax), offset) ||
     337       595800 :         poly.around(Position(myXmax, myYmin), offset) ||
     338       595583 :         poly.around(Position(myXmin, myYmin), offset);
     339              : }
     340              : 
     341              : 
     342              : Boundary&
     343      1068127 : Boundary::grow(double by) {
     344              : 
     345      1068127 :     myXmax += by;
     346      1068127 :     myYmax += by;
     347      1068127 :     myXmin -= by;
     348      1068127 :     myYmin -= by;
     349      1068127 :     return *this;
     350              : }
     351              : 
     352              : 
     353              : Boundary&
     354            0 : Boundary::scale(double by) {
     355            0 :     growWidth(by * (myXmax - myXmin));
     356            0 :     growHeight(by * (myYmax - myYmin));
     357            0 :     return *this;
     358              : }
     359              : 
     360              : 
     361              : void
     362      1864865 : Boundary::growWidth(double by) {
     363      1864865 :     myXmin -= by;
     364      1864865 :     myXmax += by;
     365      1864865 : }
     366              : 
     367              : 
     368              : void
     369      1145983 : Boundary::growHeight(double by) {
     370      1145983 :     myYmin -= by;
     371      1145983 :     myYmax += by;
     372      1145983 : }
     373              : 
     374              : void
     375           24 : Boundary::flipY() {
     376           24 :     myYmin *= -1.0;
     377           24 :     myYmax *= -1.0;
     378              :     double tmp = myYmin;
     379           24 :     myYmin = myYmax;
     380           24 :     myYmax = tmp;
     381           24 : }
     382              : 
     383              : 
     384              : 
     385              : std::ostream&
     386         7008 : operator<<(std::ostream& os, const Boundary& b) {
     387        28032 :     os << b.myXmin << "," << b.myYmin << "," << b.myXmax << "," << b.myYmax;
     388         7008 :     return os;
     389              : }
     390              : 
     391              : 
     392              : bool
     393          370 : Boundary::operator==(const Boundary& b) const {
     394              :     return (
     395          370 :                myXmin == b.myXmin &&
     396            0 :                myXmax == b.myXmax &&
     397            0 :                myYmin == b.myYmin &&
     398            0 :                myYmax == b.myYmax &&
     399            0 :                myZmin == b.myZmin &&
     400          370 :                myZmax == b.myZmax &&
     401            0 :                myWasInitialised == b.myWasInitialised);
     402              : }
     403              : 
     404              : 
     405              : bool
     406            0 : Boundary::operator!=(const Boundary& b) const {
     407            0 :     return !(*this == b);
     408              : }
     409              : 
     410              : 
     411              : void
     412          411 : Boundary::set(double xmin, double ymin, double xmax, double ymax) {
     413              :     /*
     414              :         Takes care of the following extraneous cases w.r.t the input parameters:
     415              :             - xmin > xmax
     416              :             - ymin > ymax
     417              :     */
     418              : 
     419          411 :     myXmin = MIN2(xmin, xmax);
     420          411 :     myYmin = MIN2(ymin, ymax);
     421          411 :     myXmax = MAX2(xmin, xmax);
     422          411 :     myYmax = MAX2(ymin, ymax);
     423          411 : }
     424              : 
     425              : 
     426              : void
     427            2 : Boundary::setOffsets(double xmin, double ymin, double xmax, double ymax) {
     428            2 :     myXmin = xmin;
     429            2 :     myYmin = ymin;
     430            2 :     myXmax = xmax;
     431            2 :     myYmax = ymax;
     432            2 : }
     433              : 
     434              : 
     435              : void
     436         1247 : Boundary::moveby(double x, double y, double z) {
     437         1247 :     myXmin += x;
     438         1247 :     myYmin += y;
     439         1247 :     myZmin += z;
     440         1247 :     myXmax += x;
     441         1247 :     myYmax += y;
     442         1247 :     myZmax += z;
     443         1247 : }
     444              : 
     445              : 
     446              : PositionVector
     447         2068 : Boundary::getShape(const bool closeShape) const {
     448         2068 :     PositionVector shape;
     449         2068 :     shape.push_back(Position(myXmin, myYmin));
     450         2068 :     shape.push_back(Position(myXmin, myYmax));
     451         2068 :     shape.push_back(Position(myXmax, myYmax));
     452         2068 :     shape.push_back(Position(myXmax, myYmin));
     453         2068 :     if (closeShape) {
     454         2068 :         shape.push_back(Position(myXmin, myYmin));
     455              :     }
     456         2068 :     return shape;
     457            0 : }
     458              : 
     459              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1