LCOV - code coverage report
Current view: top level - src/utils/geom - Position.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 85 86 98.8 %
Date: 2024-05-07 15:28:01 Functions: 6 6 100.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    Position.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Axel Wegener
      18             : /// @author  Michael Behrisch
      19             : /// @date    Sept 2002
      20             : ///
      21             : // A position in the 2D- or 3D-world
      22             : /****************************************************************************/
      23             : #pragma once
      24             : #include <config.h>
      25             : #include <iostream>
      26             : #include <cmath>
      27             : 
      28             : #include <config.h>
      29             : 
      30             : // ===========================================================================
      31             : // class definitions
      32             : // ===========================================================================
      33             : /**
      34             :  * @class Position
      35             :  * @brief A point in 2D or 3D with translation and scaling methods.
      36             :  */
      37             : class Position {
      38             : public:
      39             :     /// @brief default constructor
      40      826354 :     Position() :
      41   953443339 :         myX(0.0), myY(0.0), myZ(0.0) { }
      42             : 
      43             :     /// @brief Parametrised constructor (only for x-y)
      44   197543816 :     Position(double x, double y) :
      45    28421898 :         myX(x), myY(y), myZ(0) { }
      46             : 
      47             :     /// @brief Parametrised constructor
      48     2372351 :     Position(double x, double y, double z) :
      49    19832680 :         myX(x), myY(y), myZ(z) { }
      50             : 
      51             :     /// @brief Destructor
      52  4533512755 :     ~Position() { }
      53             : 
      54             :     /// @brief Returns the x-position
      55             :     inline double x() const {
      56   428498334 :         return myX;
      57             :     }
      58             : 
      59             :     /// @brief Returns the y-position
      60             :     inline double y() const {
      61   641513498 :         return myY;
      62             :     }
      63             : 
      64             :     /// @brief Returns the z-position
      65             :     inline double z() const {
      66    30665759 :         return myZ;
      67             :     }
      68             : 
      69             :     /// @brief set position x
      70             :     void setx(double x) {
      71        1227 :         myX = x;
      72           2 :     }
      73             : 
      74             :     /// @brief set position y
      75             :     void sety(double y) {
      76        6768 :         myY = y;
      77          26 :     }
      78             : 
      79             :     /// @brief set position z
      80             :     void setz(double z) {
      81     1047240 :         myZ = z;
      82        6132 :     }
      83             : 
      84             :     /// @brief set positions x and y
      85             :     void set(double x, double y) {
      86     1044625 :         myX = x;
      87      179237 :         myY = y;
      88             :     }
      89             : 
      90             :     /// @brief set positions x, y and z
      91             :     void set(double x, double y, double z) {
      92      798312 :         myX = x;
      93      798312 :         myY = y;
      94     4118931 :         myZ = z;
      95       12549 :     }
      96             : 
      97             :     /// @brief set position with another position
      98             :     void set(const Position& pos) {
      99      480589 :         myX = pos.myX;
     100      480589 :         myY = pos.myY;
     101      480589 :         myZ = pos.myZ;
     102           6 :     }
     103             : 
     104             :     /// @brief Multiplies position with the given value
     105             :     void mul(double val) {
     106       50796 :         myX *= val;
     107       50796 :         myY *= val;
     108       50754 :         myZ *= val;
     109       38110 :     }
     110             : 
     111             :     /// @brief Divides position with the given value
     112             :     void div(double val) {
     113             :         myX /= val;
     114             :         myY /= val;
     115             :         myZ /= val;
     116             :     }
     117             : 
     118             :     /// @brief Multiplies position with the given values
     119             :     void mul(double mx, double my) {
     120             :         myX *= mx;
     121       18324 :         myY *= my;
     122          23 :     }
     123             : 
     124             :     /// @brief Multiplies position with the given values
     125             :     void mul(double mx, double my, double mz) {
     126             :         myX *= mx;
     127             :         myY *= my;
     128             :         myZ *= mz;
     129             :     }
     130             : 
     131             :     /// @brief Adds the given position to this one
     132             :     void add(const Position& pos) {
     133     7596728 :         myX += pos.myX;
     134     7596728 :         myY += pos.myY;
     135     7596728 :         myZ += pos.myZ;
     136     6492521 :     }
     137             : 
     138             :     /// @brief Adds the given position to this one
     139             :     void add(double dx, double dy) {
     140        2683 :         myX += dx;
     141        2683 :         myY += dy;
     142        1411 :     }
     143             : 
     144             :     /// @brief Adds the given position to this one
     145             :     void add(double dx, double dy, double dz) {
     146     7617570 :         myX += dx;
     147     7617570 :         myY += dy;
     148     7617570 :         myZ += dz;
     149             :     }
     150             : 
     151             :     /// @brief Subtracts the given position from this one
     152             :     void sub(double dx, double dy) {
     153       28263 :         myX -= dx;
     154       28263 :         myY -= dy;
     155             :     }
     156             : 
     157             :     /// @brief Subtracts the given position from this one
     158             :     void sub(double dx, double dy, double dz) {
     159             :         myX -= dx;
     160             :         myY -= dy;
     161             :         myZ -= dz;
     162             :     }
     163             : 
     164             :     /// @brief Subtracts the given position from this one
     165             :     void sub(const Position& pos) {
     166     8692367 :         myX -= pos.myX;
     167     8692367 :         myY -= pos.myY;
     168     8692367 :         myZ -= pos.myZ;
     169     1722988 :     }
     170             : 
     171             :     /// @brief Computes the length of the given vector
     172             :     inline double length2D() const {
     173        2816 :         return sqrt(myX * myX + myY * myY);
     174             :     }
     175             : 
     176             :     /// @brief Normalizes the given vector
     177        1592 :     inline void norm2D() {
     178             :         const double val = length2D();
     179        1592 :         if (val != 0.) {
     180        1592 :             myX /= val;
     181        1592 :             myY /= val;
     182             :         }
     183        1592 :     }
     184             : 
     185             :     /// @brief output operator
     186     2292546 :     friend std::ostream& operator<<(std::ostream& os, const Position& p) {
     187             :         os << p.x() << "," << p.y();
     188     2292546 :         if (p.z() != double(0.0)) {
     189             :             os << "," << p.z();
     190             :         }
     191     2292546 :         return os;
     192             :     }
     193             : 
     194             :     /// @brief add operator
     195             :     Position operator+(const Position& p2) const {
     196    21651482 :         return Position(myX + p2.myX,  myY + p2.myY, myZ + p2.myZ);
     197             :     }
     198             : 
     199             :     /// @brief sub operator
     200             :     Position operator-(const Position& p2) const {
     201    47398285 :         return Position(myX - p2.myX,  myY - p2.myY, myZ - p2.myZ);
     202             :     }
     203             : 
     204             :     /// @brief keep the direction but modify the length of the (location) vector to length * scalar
     205             :     Position operator*(double scalar) const {
     206  1717259209 :         return Position(myX * scalar, myY * scalar, myZ * scalar);
     207             :     }
     208             : 
     209             :     /// @brief keep the direction but modify the length of the (location) vector to length / scalar
     210             :     Position operator/(double scalar) const {
     211           6 :         return Position(myX / scalar, myY / scalar, myZ / scalar);
     212             :     }
     213             : 
     214             :     /// @brief keep the direction but modify the length of the (location) vector to length + scalar
     215        5344 :     Position operator+(double offset) const {
     216        5344 :         const double length = distanceTo(Position(0, 0, 0));
     217        5344 :         if (length == 0) {
     218           0 :             return *this;
     219             :         }
     220        5344 :         const double scalar = (length + offset) / length;
     221        5344 :         return Position(myX * scalar, myY * scalar, myZ * scalar);
     222             :     }
     223             : 
     224             :     /// @brief keep the direction but modify the length of the (location) vector to length - scalar
     225             :     Position operator-(double offset) const {
     226             :         const double length = distanceTo(Position(0, 0, 0));
     227             :         if (length == 0) {
     228             :             return *this;
     229             :         }
     230             :         const double scalar = (length - offset) / length;
     231             :         return Position(myX * scalar, myY * scalar, myZ * scalar);
     232             :     }
     233             : 
     234             :     /// @brief comparation operator
     235             :     bool operator==(const Position& p2) const {
     236  2646476093 :         return myX == p2.myX && myY == p2.myY && myZ == p2.myZ;
     237             :     }
     238             : 
     239             :     /// @brief difference  operator
     240             :     bool operator!=(const Position& p2) const {
     241  1043851003 :         return myX != p2.myX || myY != p2.myY || myZ != p2.myZ;
     242             :     }
     243             : 
     244             :     /// @brief lexicographical sorting for use in maps and sets
     245             :     bool operator<(const Position& p2) const {
     246       10518 :         if (myX < p2.myX) {
     247             :             return true;
     248        6889 :         } else if (myY < p2.myY) {
     249             :             return true;
     250             :         } else {
     251        4887 :             return myZ < p2.myZ;
     252             :         }
     253             :     }
     254             : 
     255             :     /// @brief check if two position is almost the sme as other
     256             :     bool almostSame(const Position& p2, double maxDiv = POSITION_EPS) const {
     257    10841905 :         return distanceTo(p2) < maxDiv;
     258             :     }
     259             : 
     260             :     /// @brief returns the euclidean distance in 3 dimension
     261  3663339573 :     inline double distanceTo(const Position& p2) const {
     262  3663339573 :         return sqrt(distanceSquaredTo(p2));
     263             :     }
     264             : 
     265             :     /// @brief returns the square of the distance to another position
     266             :     inline double distanceSquaredTo(const Position& p2) const {
     267  3663339573 :         return (myX - p2.myX) * (myX - p2.myX) + (myY - p2.myY) * (myY - p2.myY) + (myZ - p2.myZ) * (myZ - p2.myZ);
     268             :     }
     269             : 
     270             :     /// @brief returns the euclidean distance in the x-y-plane
     271             :     inline double distanceTo2D(const Position& p2) const {
     272   342008354 :         return sqrt(distanceSquaredTo2D(p2));
     273             :     }
     274             : 
     275             :     /// @brief returns the square of the distance to another position (Only using x and y positions)
     276             :     inline double distanceSquaredTo2D(const Position& p2) const {
     277   566871905 :         return (myX - p2.myX) * (myX - p2.myX) + (myY - p2.myY) * (myY - p2.myY);
     278             :     }
     279             : 
     280             :     /// @brief returns the angle in the plane of the vector pointing from here to the other position (in radians between -M_PI and M_PI)
     281             :     inline double angleTo2D(const Position& other) const {
     282   742410083 :         return atan2(other.myY - myY, other.myX - myX);
     283             :     }
     284             : 
     285             :     /// @brief returns the slope of the vector pointing from here to the other position (in radians between -M_PI and M_PI)
     286   250433708 :     inline double slopeTo2D(const Position& other) const {
     287   250433708 :         return atan2(other.myZ - myZ, distanceTo2D(other));
     288             :     }
     289             : 
     290             :     /// @brief returns the cross product between this point and the second one
     291             :     Position crossProduct(const Position& pos) {
     292             :         return Position(
     293         360 :                    myY * pos.myZ - myZ * pos.myY,
     294         360 :                    myZ * pos.myX - myX * pos.myZ,
     295         360 :                    myX * pos.myY - myY * pos.myX);
     296             :     }
     297             : 
     298             :     /// @brief returns the dot product (scalar product) between this point and the second one
     299             :     inline double dotProduct(const Position& pos) const {
     300         360 :         return myX * pos.myX + myY * pos.myY + myZ * pos.myZ;
     301             :     }
     302             : 
     303             :     /// @brief rotate this position by rad around origin and return the result
     304             :     Position rotateAround2D(double rad, const Position& origin);
     305             : 
     306             :     /// @brief swap position X and Y
     307             :     void swapXY() {
     308             :         std::swap(myX, myY);
     309             :     }
     310             : 
     311             :     /// @brief check if position is NAN
     312             :     bool isNAN() const {
     313       14367 :         return (std::isnan(myX) || std::isnan(myY) || std::isnan(myZ));
     314             :     }
     315             : 
     316             :     /// @brief used to indicate that a position is valid
     317             :     static const Position INVALID;
     318             : 
     319             : private:
     320             :     /// @brief  The x-position
     321             :     double myX;
     322             : 
     323             :     /// @brief  The y-position
     324             :     double myY;
     325             : 
     326             :     /// @brief  The z-position
     327             :     double myZ;
     328             : };

Generated by: LCOV version 1.14