LCOV - code coverage report
Current view: top level - src/utils/geom - PositionVector.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 1 1
Test Date: 2024-11-22 15:46:21 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     52638480 : 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 rotate all points around the first element
     252              :     void rotateAroundFirstElement2D(double angle);
     253              : 
     254              :     //// @brief append the given vector to this one
     255              :     void append(const PositionVector& v, double sameThreshold = 2.0);
     256              : 
     257              :     //// @brief prepend the given vector to this one
     258              :     void prepend(const PositionVector& v, double sameThreshold = 2.0);
     259              : 
     260              :     /// @brief get subpart of a position vector
     261              :     PositionVector getSubpart(double beginOffset, double endOffset) const;
     262              : 
     263              :     /// @brief get subpart of a position vector in two dimensions (Z is ignored)
     264              :     PositionVector getSubpart2D(double beginOffset, double endOffset) const;
     265              : 
     266              :     /// @brief get subpart of a position vector using index and a cout
     267              :     PositionVector getSubpartByIndex(int beginIndex, int count) const;
     268              : 
     269              :     /// @brief sort as polygon CW by angle
     270              :     /// @remark this function works for non-convex polygons but won't possibly yield the desired polygon
     271              :     void sortAsPolyCWByAngle();
     272              : 
     273              :     /// @brief sort by increasing X-Y Positions
     274              :     void sortByIncreasingXY();
     275              : 
     276              :     /// @brief extrapolate position vector
     277              :     void extrapolate(const double val, const bool onlyFirst = false, const bool onlyLast = false);
     278              : 
     279              :     /// @brief extrapolate position vector in two dimensions (Z is ignored)
     280              :     void extrapolate2D(const double val, const bool onlyFirst = false);
     281              : 
     282              :     /// @brief reverse position vector
     283              :     PositionVector reverse() const;
     284              : 
     285              :     /// @brief get a side position of position vector using a offset
     286              :     static Position sideOffset(const Position& beg, const Position& end, const double amount);
     287              : 
     288              :     /// @brief move position vector to side using certain amount
     289              :     void move2side(double amount, double maxExtension = 100);
     290              : 
     291              :     /// @brief move position vector to side using a custom offset for each geometry point
     292              :     void move2sideCustom(std::vector<double> amount, double maxExtension = 100);
     293              : 
     294              :     /// @brief get angle in certain position of position vector (in radians between -M_PI and M_PI)
     295              :     double angleAt2D(int pos) const;
     296              : 
     297              :     /**@brief inserts p between the two closest positions
     298              :      * @param p position to be inserted
     299              :      * @param interpolateZ flag to enable/disable interpolation of Z Value between the two closest positions
     300              :      * @return the insertion index
     301              :      */
     302              :     int insertAtClosest(const Position& p, bool interpolateZ);
     303              : 
     304              :     /// @brief removes the point closest to p and return the removal index
     305              :     int removeClosest(const Position& p);
     306              : 
     307              :     /// @brief comparing operation
     308              :     bool operator==(const PositionVector& v2) const;
     309              : 
     310              :     /// @brief comparing operation
     311              :     bool operator!=(const PositionVector& v2) const;
     312              : 
     313              :     /// @brief subtracts two vectors (requires vectors of the same length)
     314              :     PositionVector operator-(const PositionVector& v2) const;
     315              : 
     316              :     /// @brief adds two vectors (requires vectors of the same length)
     317              :     PositionVector operator+(const PositionVector& v2) const;
     318              : 
     319              :     /// @brief class for CW Sorter
     320              :     class as_poly_cw_sorter {
     321              :     public:
     322              :         /// @brief constructor
     323              :         as_poly_cw_sorter();
     324              : 
     325              :         /// @brief comparing operation for sort
     326              :         int operator()(const Position& p1, const Position& p2) const;
     327              : 
     328              :     private:
     329              :         /// @brief computes the angle of the given vector, in the range $[0,2*\pi[$
     330              :         double atAngle2D(const Position& p) const;
     331              :     };
     332              : 
     333              :     /// @brief clase for increasing Sorter
     334              :     class increasing_x_y_sorter {
     335              :     public:
     336              :         /// constructor
     337              :         explicit increasing_x_y_sorter();
     338              : 
     339              :         /// comparing operation
     340              :         int operator()(const Position& p1, const Position& p2) const;
     341              :     };
     342              : 
     343              :     /// @brief get left
     344              :     /// @note previously marked with "!!!"
     345              :     double isLeft(const Position& P0, const Position& P1, const Position& P2) const;
     346              : 
     347              :     /// @brief returns the angle in radians of the line connecting the first and the last position
     348              :     double beginEndAngle() const;
     349              : 
     350              :     /// @brief return the nearest offest to point 2D
     351              :     double nearest_offset_to_point2D(const Position& p, bool perpendicular = true) const;
     352              : 
     353              :     /// @brief return the nearest offest to point 2D projected onto the 3D geometry
     354              :     double nearest_offset_to_point25D(const Position& p, bool perpendicular = true) const;
     355              : 
     356              :     /** @brief return position p within the length-wise coordinate system
     357              :      * defined by this position vector. The x value is the same as that returned
     358              :      * by nearest_offset_to_point2D(p) and the y value is the perpendicular distance to this
     359              :      * vector with the sign indicating the side (right is postive).
     360              :      * if extend is true, the vector is extended on both sides and the
     361              :      * x-coordinate of the result may be below 0 or above the length of the original vector
     362              :      */
     363              :     Position transformToVectorCoordinates(const Position& p, bool extend = false) const;
     364              : 
     365              :     /* @brief index of the closest position to p
     366              :      * @in twoD whether all positions should be projected onto the plan
     367              :        @note: may only be called for a non-empty vector
     368              :     */
     369              :     int indexOfClosest(const Position& p, bool twoD = false) const;
     370              : 
     371              :     /// @brief distances of all my points to s and all of s points to myself
     372              :     /// @note if perpendicular is set to true, only the perpendicular distances are returned
     373              :     std::vector<double> distances(const PositionVector& s, bool perpendicular = false) const;
     374              : 
     375              :     /// @brief closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
     376              :     double distance2D(const Position& p, bool perpendicular = false) const;
     377              : 
     378              :     /// @brief insert in front a Position
     379              :     void push_front(const Position& p);
     380              : 
     381              :     /// @brief pop first Position
     382              :     void pop_front();
     383              : 
     384              :     /// @brief insert in back a non double position
     385              :     void push_back_noDoublePos(const Position& p);
     386              : 
     387              :     /// @brief insert in front a non double position
     388              :     void push_front_noDoublePos(const Position& p);
     389              : 
     390              :     /// @brief insert in front a non double position
     391              :     void insert_noDoublePos(const std::vector<Position>::iterator& at, const Position& p);
     392              : 
     393              :     /// @brief check if PositionVector is closed
     394              :     bool isClosed() const;
     395              : 
     396              :     /// @brief check if PositionVector is NAN
     397              :     bool isNAN() const;
     398              : 
     399              :     /** @brief Removes positions if too near
     400              :      * @param[in] minDist The minimum accepted distance; default: POSITION_EPS
     401              :      * @param[in] assertLength Whether the result must at least contain two points (be a line); default: false, to ensure original behaviour
     402              :      */
     403              :     void removeDoublePoints(double minDist = POSITION_EPS, bool assertLength = false, int beginOffset = 0, int endOffset = 0, bool resample = false);
     404              : 
     405              :     /// @brief return whether two positions differ in z-coordinate
     406              :     bool hasElevation() const;
     407              : 
     408              :     /// @brief return the same shape with intermediate colinear points removed
     409              :     PositionVector simplified() const;
     410              :     // test implementation of an alternative check
     411              :     const PositionVector simplified2(const bool closed, const double eps = NUMERICAL_EPS) const;
     412              : 
     413              :     /** @brief return orthogonal through p (extending this vector if necessary)
     414              :      * @param[in] p The point through which to draw the orthogonal
     415              :      * @param[in] extend how long to extend this vector for finding an orthogonal
     416              :      * @param[in] front Whether to take the segment before or after the base point in case of ambiguity
     417              :      * @param[in] length the length of the orthogonal
     418              :      * @param[in] deg the rotation angle relative to the shape direction
     419              :      */
     420              :     PositionVector getOrthogonal(const Position& p, double extend, bool before, double length = 1.0, double deg = 90) const;
     421              : 
     422              :     /// @brief returned vector that is smoothed at the front (within dist)
     423              :     PositionVector smoothedZFront(double dist = std::numeric_limits<double>::max()) const;
     424              : 
     425              :     /// @brief returned vector that varies z smoothly over its length
     426              :     PositionVector interpolateZ(double zStart, double zEnd) const;
     427              : 
     428              :     /**@brief resample shape (i.e. transform to segments, equal spacing)
     429              :      * @param[in] maxLength length of every segment
     430              :      * @param[in] adjustEnd enable or disable adjust end (i.e. result has the same original length, last segment could be short)
     431              :      */
     432              :     PositionVector resample(double maxLength, const bool adjustEnd) const;
     433              : 
     434              :     /// @brief return the offset at the given index
     435              :     double offsetAtIndex2D(int index) const;
     436              : 
     437              :     /* @brief return the maximum grade of all segments as a fraction of zRange/length2D
     438              :      * @param[out] maxJump The maximum vertical jump (with grade infinity)
     439              :      */
     440              :     double getMaxGrade(double& maxJump) const;
     441              : 
     442              :     /// @brief return minimum z-coordinate
     443              :     double getMinZ() const;
     444              : 
     445              :     /// @brief check if the two vectors have the same length and pairwise similar positions
     446              :     bool almostSame(const PositionVector& v2, double maxDiv = POSITION_EPS) const;
     447              : 
     448              :     /// @brief return a bezier interpolation
     449              :     PositionVector bezier(int numPoints);
     450              : 
     451              :     static double localAngle(const Position& from, const Position& pos, const Position& to);
     452              : 
     453              :     /* @brief checks if the polygon represented by the PositionVector is clockwise-oriented
     454              :        @remark this function works for non-convex polygons
     455              :     */
     456              :     bool isClockwiseOriented(void);
     457              : 
     458              : private:
     459              :     /// @brief return whether the line segments defined by Line p11,p12 and Line p21,p22 intersect
     460              :     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);
     461              : };
        

Generated by: LCOV version 2.0-1