LCOV - code coverage report
Current view: top level - src/utils/geom - Boundary.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 187 216 86.6 %
Date: 2024-05-07 15:28:01 Functions: 34 40 85.0 %

          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     4117050 : Boundary::Boundary()
      36     4117050 :     : myXmin(10000000000.0), myXmax(-10000000000.0),
      37     4117050 :       myYmin(10000000000.0), myYmax(-10000000000.0),
      38     4117050 :       myZmin(10000000000.0), myZmax(-10000000000.0),
      39     4117050 :       myWasInitialised(false) {}
      40             : 
      41             : 
      42      106794 : Boundary::Boundary(double x1, double y1, double x2, double y2)
      43      106794 :     : myXmin(10000000000.0), myXmax(-10000000000.0),
      44      106794 :       myYmin(10000000000.0), myYmax(-10000000000.0),
      45      106794 :       myZmin(10000000000.0), myZmax(-10000000000.0),
      46      106794 :       myWasInitialised(false) {
      47      106794 :     add(x1, y1);
      48      106794 :     add(x2, y2);
      49      106794 : }
      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    10098872 : Boundary::~Boundary() {}
      63             : 
      64             : 
      65             : void
      66        2384 : Boundary::reset() {
      67        2384 :     myXmin = 10000000000.0;
      68        2384 :     myXmax = -10000000000.0;
      69        2384 :     myYmin = 10000000000.0;
      70        2384 :     myYmax = -10000000000.0;
      71        2384 :     myZmin = 10000000000.0;
      72        2384 :     myZmax = -10000000000.0;
      73        2384 :     myWasInitialised = false;
      74        2384 : }
      75             : 
      76             : 
      77             : void
      78    12234926 : Boundary::add(double x, double y, double z) {
      79    12234926 :     if (!myWasInitialised) {
      80     3603396 :         myYmin = y;
      81     3603396 :         myYmax = y;
      82     3603396 :         myXmin = x;
      83     3603396 :         myXmax = x;
      84     3603396 :         myZmin = z;
      85     3603396 :         myZmax = z;
      86             :     } else {
      87     8631530 :         myXmin = myXmin < x ? myXmin : x;
      88     8631530 :         myXmax = myXmax > x ? myXmax : x;
      89     8631530 :         myYmin = myYmin < y ? myYmin : y;
      90     8631530 :         myYmax = myYmax > y ? myYmax : y;
      91     8631530 :         myZmin = myZmin < z ? myZmin : z;
      92     8686856 :         myZmax = myZmax > z ? myZmax : z;
      93             :     }
      94    12234926 :     myWasInitialised = true;
      95    12234926 : }
      96             : 
      97             : 
      98             : void
      99    10352911 : Boundary::add(const Position& p) {
     100    10352911 :     add(p.x(), p.y(), p.z());
     101    10352911 : }
     102             : 
     103             : 
     104             : void
     105      832773 : Boundary::add(const Boundary& p) {
     106      832773 :     add(p.xmin(), p.ymin(), p.zmin());
     107      832773 :     add(p.xmax(), p.ymax(), p.zmax());
     108      832773 : }
     109             : 
     110             : 
     111             : Position
     112      310728 : Boundary::getCenter() const {
     113      310728 :     return Position((myXmin + myXmax) / (double) 2.0, (myYmin + myYmax) / (double) 2.0, (myZmin + myZmax) / (double) 2.0);
     114             : }
     115             : 
     116             : 
     117             : double
     118     2842546 : Boundary::xmin() const {
     119     2842546 :     return myXmin;
     120             : }
     121             : 
     122             : 
     123             : double
     124     2357091 : Boundary::xmax() const {
     125     2357091 :     return myXmax;
     126             : }
     127             : 
     128             : 
     129             : double
     130     3013400 : Boundary::ymin() const {
     131     3013400 :     return myYmin;
     132             : }
     133             : 
     134             : 
     135             : double
     136     2528679 : Boundary::ymax() const {
     137     2528679 :     return myYmax;
     138             : }
     139             : 
     140             : 
     141             : double
     142      832783 : Boundary::zmin() const {
     143      832783 :     return myZmin;
     144             : }
     145             : 
     146             : 
     147             : double
     148      832783 : Boundary::zmax() const {
     149      832783 :     return myZmax;
     150             : }
     151             : 
     152             : 
     153             : double
     154     9936582 : Boundary::getWidth() const {
     155     9936582 :     return myXmax - myXmin;
     156             : }
     157             : 
     158             : 
     159             : double
     160     6998009 : Boundary::getHeight() const {
     161     6998009 :     return myYmax - myYmin;
     162             : }
     163             : 
     164             : 
     165             : double
     166        1835 : Boundary::getZRange() const {
     167        1835 :     return myZmax - myZmin;
     168             : }
     169             : 
     170             : 
     171             : bool
     172      792208 : Boundary::around(const Position& p, double offset) const {
     173             :     return
     174      401419 :         (p.x() <= myXmax + offset && p.x() >= myXmin - offset) &&
     175      803571 :         (p.y() <= myYmax + offset && p.y() >= myYmin - offset) &&
     176        2784 :         (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      100756 : Boundary::overlapsWith(const AbstractPoly& p, double offset) const {
     190             :     if (
     191             :         // check whether one of my points lies within the given poly
     192      199394 :         partialWithin(p, offset) ||
     193             :         // check whether the polygon lies within me
     194       98638 :         p.partialWithin(*this, offset)) {
     195        2231 :         return true;
     196             :     }
     197             :     // check whether the bounderies cross
     198             :     return
     199      197050 :         p.crosses(Position(myXmax + offset, myYmax + offset), Position(myXmin - offset, myYmax + offset))
     200       98525 :         ||
     201       98525 :         p.crosses(Position(myXmin - offset, myYmax + offset), Position(myXmin - offset, myYmin - offset))
     202       98523 :         ||
     203       98523 :         p.crosses(Position(myXmin - offset, myYmin - offset), Position(myXmax + offset, myYmin - offset))
     204      197048 :         ||
     205      197048 :         p.crosses(Position(myXmax + offset, myYmin - offset), Position(myXmax + offset, myYmax + offset));
     206             : }
     207             : 
     208             : 
     209             : bool
     210      393216 : Boundary::crosses(const Position& p1, const Position& p2) const {
     211      393216 :     const PositionVector line(p1, p2);
     212             :     return
     213      393216 :         line.intersects(Position(myXmax, myYmax), Position(myXmin, myYmax))
     214      393212 :         ||
     215      393212 :         line.intersects(Position(myXmin, myYmax), Position(myXmin, myYmin))
     216      393210 :         ||
     217      393210 :         line.intersects(Position(myXmin, myYmin), Position(myXmax, myYmin))
     218      786424 :         ||
     219      786424 :         line.intersects(Position(myXmax, myYmin), Position(myXmax, myYmax));
     220      393216 : }
     221             : 
     222             : 
     223             : double
     224           0 : Boundary::contains(const Boundary& b) const {
     225           0 :     if ((myXmin <= b.xmin()) && (myYmin <= b.ymin()) &&
     226           0 :             (myXmax >= b.xmax()) && (myYmax >= b.ymax())) {
     227             :         return true;
     228             :     } else {
     229           0 :         return false;
     230             :     }
     231             : }
     232             : 
     233             : 
     234             : bool
     235           0 : Boundary::isInitialised() const {
     236           0 :     return myWasInitialised;
     237             : }
     238             : 
     239             : 
     240             : double
     241        6470 : Boundary::distanceTo2D(const Position& p) const {
     242        6470 :     const double leftDist = myXmin - p.x();
     243        6470 :     const double rightDist = p.x() - myXmax;
     244        6470 :     const double bottomDist = myYmin - p.y();
     245        6470 :     const double topDist = p.y() - myYmax;
     246        6470 :     if (leftDist > 0.) {
     247        4645 :         if (bottomDist > 0.) {
     248        3440 :             return sqrt(leftDist * leftDist + bottomDist * bottomDist);
     249             :         }
     250        1205 :         if (topDist > 0.) {
     251         470 :             return sqrt(leftDist * leftDist + topDist * topDist);
     252             :         }
     253             :         return leftDist;
     254             :     }
     255        1825 :     if (rightDist > 0.) {
     256         244 :         if (bottomDist > 0.) {
     257         180 :             return sqrt(rightDist * rightDist + bottomDist * bottomDist);
     258             :         }
     259          64 :         if (topDist > 0.) {
     260          24 :             return sqrt(rightDist * rightDist + topDist * topDist);
     261             :         }
     262             :         return rightDist;
     263             :     }
     264        1581 :     if (bottomDist > 0) {
     265             :         return bottomDist;
     266             :     }
     267         885 :     if (topDist > 0) {
     268          48 :         return topDist;
     269             :     }
     270             :     return 0.;
     271             : }
     272             : 
     273             : 
     274             : double
     275       27789 : Boundary::distanceTo2D(const Boundary& b) const {
     276       27789 :     const double leftDist = myXmin - b.myXmax;
     277       27789 :     const double rightDist = b.myXmin - myXmax;
     278       27789 :     const double bottomDist = myYmin - b.myYmax;
     279       27789 :     const double topDist = b.myYmin - myYmax;
     280       27789 :     if (leftDist > 0.) {
     281        1282 :         if (bottomDist > 0.) {
     282         203 :             return sqrt(leftDist * leftDist + bottomDist * bottomDist);
     283             :         }
     284        1079 :         if (topDist > 0.) {
     285         448 :             return sqrt(leftDist * leftDist + topDist * topDist);
     286             :         }
     287             :         return leftDist;
     288             :     }
     289       26507 :     if (rightDist > 0.) {
     290       11921 :         if (bottomDist > 0.) {
     291         264 :             return sqrt(rightDist * rightDist + bottomDist * bottomDist);
     292             :         }
     293       11657 :         if (topDist > 0.) {
     294        6837 :             return sqrt(rightDist * rightDist + topDist * topDist);
     295             :         }
     296             :         return rightDist;
     297             :     }
     298       14586 :     if (bottomDist > 0) {
     299             :         return bottomDist;
     300             :     }
     301       13452 :     if (topDist > 0) {
     302        3363 :         return topDist;
     303             :     }
     304             :     return 0.;
     305             : }
     306             : 
     307             : 
     308             : bool
     309      199178 : Boundary::partialWithin(const AbstractPoly& poly, double offset) const {
     310             :     return
     311      396732 :         poly.around(Position(myXmax, myYmax), offset) ||
     312      394811 :         poly.around(Position(myXmin, myYmax), offset) ||
     313      593475 :         poly.around(Position(myXmax, myYmin), offset) ||
     314      197040 :         poly.around(Position(myXmin, myYmin), offset);
     315             : }
     316             : 
     317             : 
     318             : Boundary&
     319     1063006 : Boundary::grow(double by) {
     320             : 
     321     1063006 :     myXmax += by;
     322     1063006 :     myYmax += by;
     323     1063006 :     myXmin -= by;
     324     1063006 :     myYmin -= by;
     325     1063006 :     return *this;
     326             : }
     327             : 
     328             : 
     329             : Boundary&
     330           0 : Boundary::scale(double by) {
     331           0 :     growWidth(by * (myXmax - myXmin));
     332           0 :     growHeight(by * (myYmax - myYmin));
     333           0 :     return *this;
     334             : }
     335             : 
     336             : 
     337             : void
     338     1794644 : Boundary::growWidth(double by) {
     339     1794644 :     myXmin -= by;
     340     1794644 :     myXmax += by;
     341     1794644 : }
     342             : 
     343             : 
     344             : void
     345      965870 : Boundary::growHeight(double by) {
     346      965870 :     myYmin -= by;
     347      965870 :     myYmax += by;
     348      965870 : }
     349             : 
     350             : void
     351          25 : Boundary::flipY() {
     352          25 :     myYmin *= -1.0;
     353          25 :     myYmax *= -1.0;
     354             :     double tmp = myYmin;
     355          25 :     myYmin = myYmax;
     356          25 :     myYmax = tmp;
     357          25 : }
     358             : 
     359             : 
     360             : 
     361             : std::ostream&
     362        7572 : operator<<(std::ostream& os, const Boundary& b) {
     363       30288 :     os << b.myXmin << "," << b.myYmin << "," << b.myXmax << "," << b.myYmax;
     364        7572 :     return os;
     365             : }
     366             : 
     367             : 
     368             : bool
     369         370 : Boundary::operator==(const Boundary& b) const {
     370             :     return (
     371         370 :                myXmin == b.myXmin &&
     372           0 :                myXmax == b.myXmax &&
     373           0 :                myYmin == b.myYmin &&
     374           0 :                myYmax == b.myYmax &&
     375           0 :                myZmin == b.myZmin &&
     376         370 :                myZmax == b.myZmax &&
     377           0 :                myWasInitialised == b.myWasInitialised);
     378             : }
     379             : 
     380             : 
     381             : bool
     382           0 : Boundary::operator!=(const Boundary& b) const {
     383           0 :     return !(*this == b);
     384             : }
     385             : 
     386             : 
     387             : void
     388         400 : 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         400 :     myXmin = MIN2(xmin, xmax);
     396         400 :     myYmin = MIN2(ymin, ymax);
     397         400 :     myXmax = MAX2(xmin, xmax);
     398         400 :     myYmax = MAX2(ymin, ymax);
     399         400 : }
     400             : 
     401             : 
     402             : void
     403           2 : Boundary::setOffsets(double xmin, double ymin, double xmax, double ymax) {
     404           2 :     myXmin = xmin;
     405           2 :     myYmin = ymin;
     406           2 :     myXmax = xmax;
     407           2 :     myYmax = ymax;
     408           2 : }
     409             : 
     410             : 
     411             : void
     412        1825 : Boundary::moveby(double x, double y, double z) {
     413        1825 :     myXmin += x;
     414        1825 :     myYmin += y;
     415        1825 :     myZmin += z;
     416        1825 :     myXmax += x;
     417        1825 :     myYmax += y;
     418        1825 :     myZmax += z;
     419        1825 : }
     420             : 
     421             : 
     422             : PositionVector
     423        1416 : Boundary::getShape(const bool closeShape) const {
     424        1416 :     PositionVector shape;
     425        1416 :     shape.push_back(Position(myXmin, myYmin));
     426        1416 :     shape.push_back(Position(myXmin, myYmax));
     427        1416 :     shape.push_back(Position(myXmax, myYmax));
     428        1416 :     shape.push_back(Position(myXmax, myYmin));
     429        1416 :     if (closeShape) {
     430        1416 :         shape.push_back(Position(myXmin, myYmin));
     431             :     }
     432        1416 :     return shape;
     433           0 : }
     434             : 
     435             : /****************************************************************************/

Generated by: LCOV version 1.14