LCOV - code coverage report
Current view: top level - src/utils/geom - PositionVector.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 1 1 100.0 %
Date: 2024-05-07 15:28:01 Functions: 0 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    PositionVector.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @date    Sept 2002
      19             : ///
      20             : // A list of positions
      21             : /****************************************************************************/
      22             : #pragma once
      23             : #include <config.h>
      24             : 
      25             : #include <vector>
      26             : #include <limits>
      27             : #include "AbstractPoly.h"
      28             : 
      29             : 
      30             : // ===========================================================================
      31             : // class declarations
      32             : // ===========================================================================
      33             : 
      34             : class Boundary;
      35             : 
      36             : // ===========================================================================
      37             : // class definitions
      38             : // ===========================================================================
      39             : /**
      40             :  * @class PositionVector
      41             :  * @brief A list of positions
      42             :  */
      43    53876005 : class PositionVector : public AbstractPoly, private std::vector<Position> {
      44             : 
      45             : private:
      46             :     /// @brief  vector of position
      47             :     typedef std::vector<Position> vp;
      48             : 
      49             : public:
      50             :     /// @brief Constructor. Creates an empty position vector
      51             :     PositionVector();
      52             : 
      53             :     /// @brief Copy Constructor. Create a positionVector with the same elements as other positionVector
      54             :     /// @param[in] v The vector to copy
      55             :     PositionVector(const std::vector<Position>& v);
      56             : 
      57             :     /// @brief Parameter Constructor. Create a positionVector using a part of other positionVector
      58             :     /// @param[in] beg The begin iterator for copy
      59             :     /// @param[in] end The end iterator to copy
      60             :     PositionVector(const std::vector<Position>::const_iterator beg, const std::vector<Position>::const_iterator end);
      61             : 
      62             :     /// @brief Parameter Constructor used for lines
      63             :     /// @param[in] p1 the first position
      64             :     /// @param[in] p2 the second position
      65             :     PositionVector(const Position& p1, const Position& p2);
      66             : 
      67             :     /// @brief Destructor
      68             :     ~PositionVector();
      69             : 
      70             :     /// @brief empty Vector
      71             :     static const PositionVector EMPTY;
      72             : 
      73             :     /// @name methode for iterate over PositionVector
      74             :     /// @{
      75             :     /// @brief iterator
      76             :     using vp::iterator;
      77             : 
      78             :     /// @brief constant iterator
      79             :     using vp::const_iterator;
      80             : 
      81             :     /// @brief contant reference
      82             :     using vp::const_reference;
      83             : 
      84             :     /// @brief value type
      85             :     using vp::value_type;
      86             : 
      87             :     /// @brief begin of position vector
      88             :     using vp::begin;
      89             : 
      90             :     /// @brief end of position vector
      91             :     using vp::end;
      92             : 
      93             :     /// @brief push a position in the back of position vector
      94             :     using vp::push_back;
      95             : 
      96             :     /// @brief push a position in the front of position vector
      97             :     using vp::pop_back;
      98             : 
      99             :     /// @brief clear all elements of position vector
     100             :     using vp::clear;
     101             : 
     102             :     /// @brief returns size of position vector
     103             :     using vp::size;
     104             : 
     105             :     /// @brief returns whether the position vector is empty
     106             :     using vp::empty;
     107             : 
     108             :     /// @brief get the front element of position vector
     109             :     using vp::front;
     110             : 
     111             :     /// @brief get back element of position vector
     112             :     using vp::back;
     113             : 
     114             :     /// @brief get a reference of position vector
     115             :     using vp::reference;
     116             : 
     117             :     /// @brief erase a position of position vector gived by iterator
     118             :     using vp::erase;
     119             : 
     120             :     /// @brief insert a position in position vector gived by iterator
     121             :     using vp::insert;
     122             :     /// @}
     123             : 
     124             :     /// @brief Returns the information whether the position vector describes a polygon lying around the given point
     125             :     /// @note The optional offset is added to the polygon's boundaries
     126             :     bool around(const Position& p, double offset = 0) const;
     127             : 
     128             :     /// @brief Returns the information whether the given polygon overlaps with this
     129             :     /// @note Again a boundary may be specified
     130             :     bool overlapsWith(const AbstractPoly& poly, double offset = 0) const;
     131             : 
     132             :     /// @brief Returns the maximum overlaps between this and the given polygon (when not separated by at least zThreshold)
     133             :     double getOverlapWith(const PositionVector& poly, double zThreshold) const;
     134             : 
     135             :     /// @brief Returns the information whether this list of points interesects the given line
     136             :     bool intersects(const Position& p1, const Position& p2) const;
     137             : 
     138             :     /// @brief Returns the information whether this list of points interesects one the given lines
     139             :     bool intersects(const PositionVector& v1) const;
     140             : 
     141             :     /// @brief Returns the position of the intersection
     142             :     Position intersectionPosition2D(const Position& p1, const Position& p2, const double withinDist = 0.) const;
     143             : 
     144             :     /// @brief For all intersections between this vector and other, return the 2D-length of the subvector from this vectors start to the intersection
     145             :     std::vector<double> intersectsAtLengths2D(const PositionVector& other) const;
     146             : 
     147             :     /// @brief For all intersections between this vector and line, return the 2D-length of the subvector from this vectors start to the intersection
     148             :     std::vector<double> intersectsAtLengths2D(const Position& lp1, const Position& lp2) const;
     149             : 
     150             :     /// @brief Returns the position of the intersection
     151             :     Position intersectionPosition2D(const PositionVector& v1) const;
     152             : 
     153             :     /// @brief ensures that the last position equals the first
     154             :     void closePolygon();
     155             : 
     156             :     /// @brief returns the constant position at the given index, negative indices are interpreted python style
     157             :     /// @throws OutOfBoundsException if index >= size or index < -size
     158             :     const Position& operator[](int index) const;
     159             : 
     160             :     /// @brief returns the position at the given index, negative indices are interpreted python style
     161             :     /// @throws OutOfBoundsException if index >= size or index < -size
     162             :     Position& operator[](int index);
     163             : 
     164             :     /// @brief Returns the position at the given length
     165             :     Position positionAtOffset(double pos, double lateralOffset = 0) const;
     166             : 
     167             :     /// @brief Returns the position at the given length
     168             :     Position positionAtOffset2D(double pos, double lateralOffset = 0) const;
     169             : 
     170             :     /* @brief Returns position similar to positionAtOffset but instead of applying the
     171             :      * lateral offset orthogonal to the shape, apply it orthogonal to the given angle */
     172             :     Position sidePositionAtAngle(double pos, double lateralOffset, double angle) const;
     173             : 
     174             :     /// @brief Returns the rotation at the given length
     175             :     double rotationAtOffset(double pos) const;
     176             : 
     177             :     /// @brief Returns the rotation at the given length
     178             :     double rotationDegreeAtOffset(double pos) const;
     179             : 
     180             :     /// @brief Returns the slope at the given length
     181             :     double slopeDegreeAtOffset(double pos) const;
     182             : 
     183             :     /// @brief Returns the position between the two given point at the specified position
     184             :     static Position positionAtOffset(const Position& p1, const Position& p2, double pos, double lateralOffset = 0.);
     185             : 
     186             :     /// Returns the position between the two given point at the specified position
     187             :     static Position positionAtOffset2D(const Position& p1, const Position& p2, double pos, double lateralOffset = 0.);
     188             : 
     189             :     /* @brief Returns position similar to positionAtOffset but instead of applying the
     190             :      * lateral offset orthogonal to the shape, apply it orthogonal to the given angle */
     191             :     static Position sidePositionAtAngle(const Position& p1, const Position& p2, double pos, double lateralOffset, double angle);
     192             : 
     193             :     /// @brief Returns a boundary enclosing this list of lines
     194             :     Boundary getBoxBoundary() const;
     195             : 
     196             :     /// @brief Returns the arithmetic of all corner points
     197             :     /// @note: this is different from the centroid!
     198             :     Position getPolygonCenter() const;
     199             : 
     200             :     /// @brief Returns the centroid (closes the polygon if unclosed)
     201             :     Position getCentroid() const;
     202             : 
     203             :     /// @brief enlarges/shrinks the polygon by a factor based at the centroid
     204             :     void scaleRelative(double factor);
     205             : 
     206             :     /// @brief enlarges/shrinks the polygon by an absolute offset based at the centroid
     207             :     void scaleAbsolute(double offset);
     208             : 
     209             :     /// @brief get line center
     210             :     Position getLineCenter() const;
     211             : 
     212             :     /// @brief Returns the length
     213             :     double length() const;
     214             : 
     215             :     /// @brief Returns the length
     216             :     double length2D() const;
     217             : 
     218             :     /// @brief Returns the area (0 for non-closed)
     219             :     double area() const;
     220             : 
     221             :     /// @brief Returns the information whether this polygon lies partially within the given polygon
     222             :     bool partialWithin(const AbstractPoly& poly, double offset = 0) const;
     223             : 
     224             :     /// @brief Returns the two lists made when this list vector is splitted at the given point
     225             :     std::pair<PositionVector, PositionVector> splitAt(double where, bool use2D = false) const;
     226             : 
     227             :     //// @brief Output operator
     228             :     friend std::ostream& operator<<(std::ostream& os, const PositionVector& geom);
     229             : 
     230             :     //// @brief check if two positions crosses
     231             :     bool crosses(const Position& p1, const Position& p2) const;
     232             : 
     233             :     //// @brief add an offset to all positions
     234             :     void add(double xoff, double yoff, double zoff);
     235             : 
     236             :     //// @brief add an offset to all positions
     237             :     void add(const Position& offset);
     238             : 
     239             :     //// @brief subtract an offset from all positions
     240             :     void sub(const Position& offset);
     241             : 
     242             :     //// @brief adds a position without modifying the vector itself but returning the result
     243             :     PositionVector added(const Position& offset) const;
     244             : 
     245             :     //// @brief mirror coordinates along the x-axis
     246             :     void mirrorX();
     247             : 
     248             :     //// @brief rotate all points around (0,0) in the plane by the given angle
     249             :     void rotate2D(double angle);
     250             : 
     251             :     //// @brief append the given vector to this one
     252             :     void append(const PositionVector& v, double sameThreshold = 2.0);
     253             : 
     254             :     //// @brief prepend the given vector to this one
     255             :     void prepend(const PositionVector& v, double sameThreshold = 2.0);
     256             : 
     257             :     /// @brief get subpart of a position vector
     258             :     PositionVector getSubpart(double beginOffset, double endOffset) const;
     259             : 
     260             :     /// @brief get subpart of a position vector in two dimensions (Z is ignored)
     261             :     PositionVector getSubpart2D(double beginOffset, double endOffset) const;
     262             : 
     263             :     /// @brief get subpart of a position vector using index and a cout
     264             :     PositionVector getSubpartByIndex(int beginIndex, int count) const;
     265             : 
     266             :     /// @brief sort as polygon CW by angle
     267             :     /// @remark this function works for non-convex polygons but won't possibly yield the desired polygon
     268             :     void sortAsPolyCWByAngle();
     269             : 
     270             :     /// @brief sort by increasing X-Y Positions
     271             :     void sortByIncreasingXY();
     272             : 
     273             :     /// @brief extrapolate position vector
     274             :     void extrapolate(const double val, const bool onlyFirst = false, const bool onlyLast = false);
     275             : 
     276             :     /// @brief extrapolate position vector in two dimensions (Z is ignored)
     277             :     void extrapolate2D(const double val, const bool onlyFirst = false);
     278             : 
     279             :     /// @brief reverse position vector
     280             :     PositionVector reverse() const;
     281             : 
     282             :     /// @brief get a side position of position vector using a offset
     283             :     static Position sideOffset(const Position& beg, const Position& end, const double amount);
     284             : 
     285             :     /// @brief move position vector to side using certain amount
     286             :     void move2side(double amount, double maxExtension = 100);
     287             : 
     288             :     /// @brief move position vector to side using a custom offset for each geometry point
     289             :     void move2sideCustom(std::vector<double> amount, double maxExtension = 100);
     290             : 
     291             :     /// @brief get angle in certain position of position vector (in radians between -M_PI and M_PI)
     292             :     double angleAt2D(int pos) const;
     293             : 
     294             :     /**@brief inserts p between the two closest positions
     295             :      * @param p position to be inserted
     296             :      * @param interpolateZ flag to enable/disable interpolation of Z Value between the two closest positions
     297             :      * @return the insertion index
     298             :      */
     299             :     int insertAtClosest(const Position& p, bool interpolateZ);
     300             : 
     301             :     /// @brief removes the point closest to p and return the removal index
     302             :     int removeClosest(const Position& p);
     303             : 
     304             :     /// @brief comparing operation
     305             :     bool operator==(const PositionVector& v2) const;
     306             : 
     307             :     /// @brief comparing operation
     308             :     bool operator!=(const PositionVector& v2) const;
     309             : 
     310             :     /// @brief subtracts two vectors (requires vectors of the same length)
     311             :     PositionVector operator-(const PositionVector& v2) const;
     312             : 
     313             :     /// @brief adds two vectors (requires vectors of the same length)
     314             :     PositionVector operator+(const PositionVector& v2) const;
     315             : 
     316             :     /// @brief class for CW Sorter
     317             :     class as_poly_cw_sorter {
     318             :     public:
     319             :         /// @brief constructor
     320             :         as_poly_cw_sorter();
     321             : 
     322             :         /// @brief comparing operation for sort
     323             :         int operator()(const Position& p1, const Position& p2) const;
     324             : 
     325             :     private:
     326             :         /// @brief computes the angle of the given vector, in the range $[0,2*\pi[$
     327             :         double atAngle2D(const Position& p) const;
     328             :     };
     329             : 
     330             :     /// @brief clase for increasing Sorter
     331             :     class increasing_x_y_sorter {
     332             :     public:
     333             :         /// constructor
     334             :         explicit increasing_x_y_sorter();
     335             : 
     336             :         /// comparing operation
     337             :         int operator()(const Position& p1, const Position& p2) const;
     338             :     };
     339             : 
     340             :     /// @brief get left
     341             :     /// @note previously marked with "!!!"
     342             :     double isLeft(const Position& P0, const Position& P1, const Position& P2) const;
     343             : 
     344             :     /// @brief returns the angle in radians of the line connecting the first and the last position
     345             :     double beginEndAngle() const;
     346             : 
     347             :     /// @brief return the nearest offest to point 2D
     348             :     double nearest_offset_to_point2D(const Position& p, bool perpendicular = true) const;
     349             : 
     350             :     /// @brief return the nearest offest to point 2D projected onto the 3D geometry
     351             :     double nearest_offset_to_point25D(const Position& p, bool perpendicular = true) const;
     352             : 
     353             :     /** @brief return position p within the length-wise coordinate system
     354             :      * defined by this position vector. The x value is the same as that returned
     355             :      * by nearest_offset_to_point2D(p) and the y value is the perpendicular distance to this
     356             :      * vector with the sign indicating the side (right is postive).
     357             :      * if extend is true, the vector is extended on both sides and the
     358             :      * x-coordinate of the result may be below 0 or above the length of the original vector
     359             :      */
     360             :     Position transformToVectorCoordinates(const Position& p, bool extend = false) const;
     361             : 
     362             :     /* @brief index of the closest position to p
     363             :      * @in twoD whether all positions should be projected onto the plan
     364             :        @note: may only be called for a non-empty vector
     365             :     */
     366             :     int indexOfClosest(const Position& p, bool twoD = false) const;
     367             : 
     368             :     /// @brief distances of all my points to s and all of s points to myself
     369             :     /// @note if perpendicular is set to true, only the perpendicular distances are returned
     370             :     std::vector<double> distances(const PositionVector& s, bool perpendicular = false) const;
     371             : 
     372             :     /// @brief closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
     373             :     double distance2D(const Position& p, bool perpendicular = false) const;
     374             : 
     375             :     /// @brief insert in front a Position
     376             :     void push_front(const Position& p);
     377             : 
     378             :     /// @brief pop first Position
     379             :     void pop_front();
     380             : 
     381             :     /// @brief insert in back a non double position
     382             :     void push_back_noDoublePos(const Position& p);
     383             : 
     384             :     /// @brief insert in front a non double position
     385             :     void push_front_noDoublePos(const Position& p);
     386             : 
     387             :     /// @brief insert in front a non double position
     388             :     void insert_noDoublePos(const std::vector<Position>::iterator& at, const Position& p);
     389             : 
     390             :     /// @brief check if PositionVector is closed
     391             :     bool isClosed() const;
     392             : 
     393             :     /// @brief check if PositionVector is NAN
     394             :     bool isNAN() const;
     395             : 
     396             :     /** @brief Removes positions if too near
     397             :      * @param[in] minDist The minimum accepted distance; default: POSITION_EPS
     398             :      * @param[in] assertLength Whether the result must at least contain two points (be a line); default: false, to ensure original behaviour
     399             :      */
     400             :     void removeDoublePoints(double minDist = POSITION_EPS, bool assertLength = false, int beginOffset = 0, int endOffset = 0, bool resample = false);
     401             : 
     402             :     /// @brief return whether two positions differ in z-coordinate
     403             :     bool hasElevation() const;
     404             : 
     405             :     /// @brief return the same shape with intermediate colinear points removed
     406             :     PositionVector simplified() const;
     407             : 
     408             :     /** @brief return orthogonal through p (extending this vector if necessary)
     409             :      * @param[in] p The point through which to draw the orthogonal
     410             :      * @param[in] extend how long to extend this vector for finding an orthogonal
     411             :      * @param[in] front Whether to take the segment before or after the base point in case of ambiguity
     412             :      * @param[in] length the length of the orthogonal
     413             :      * @param[in] deg the rotation angle relative to the shape direction
     414             :      */
     415             :     PositionVector getOrthogonal(const Position& p, double extend, bool before, double length = 1.0, double deg = 90) const;
     416             : 
     417             :     /// @brief returned vector that is smoothed at the front (within dist)
     418             :     PositionVector smoothedZFront(double dist = std::numeric_limits<double>::max()) const;
     419             : 
     420             :     /// @brief returned vector that varies z smoothly over its length
     421             :     PositionVector interpolateZ(double zStart, double zEnd) const;
     422             : 
     423             :     /**@brief resample shape (i.e. transform to segments, equal spacing)
     424             :      * @param[in] maxLength length of every segment
     425             :      * @param[in] adjustEnd enable or disable adjust end (i.e. result has the same original length, last segment could be short)
     426             :      */
     427             :     PositionVector resample(double maxLength, const bool adjustEnd) const;
     428             : 
     429             :     /// @brief return the offset at the given index
     430             :     double offsetAtIndex2D(int index) const;
     431             : 
     432             :     /* @brief return the maximum grade of all segments as a fraction of zRange/length2D
     433             :      * @param[out] maxJump The maximum vertical jump (with grade infinity)
     434             :      */
     435             :     double getMaxGrade(double& maxJump) const;
     436             : 
     437             :     /// @brief check if the two vectors have the same length and pairwise similar positions
     438             :     bool almostSame(const PositionVector& v2, double maxDiv = POSITION_EPS) const;
     439             : 
     440             :     /// @brief return a bezier interpolation
     441             :     PositionVector bezier(int numPoints);
     442             : 
     443             :     static double localAngle(const Position& from, const Position& pos, const Position& to);
     444             : 
     445             :     /* @brief checks if the polygon represented by the PositionVector is clockwise-oriented
     446             :        @remark this function works for non-convex polygons
     447             :     */
     448             :     bool isClockwiseOriented(void);
     449             : 
     450             : private:
     451             :     /// @brief return whether the line segments defined by Line p11,p12 and Line p21,p22 intersect
     452             :     static bool intersects(const Position& p11, const Position& p12, const Position& p21, const Position& p22, const double withinDist = 0., double* x = 0, double* y = 0, double* mu = 0);
     453             : };

Generated by: LCOV version 1.14