/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GeomHelper.h14/// @author Daniel Krajzewicz15/// @author Friedemann Wesner16/// @author Jakob Erdmann17/// @author Michael Behrisch18/// @date Sept 200219///20// Some static methods performing geometrical operations21/****************************************************************************/22#pragma once23#include <config.h>2425#include <cmath>26#include "Position.h"27#include "PositionVector.h"28#include <utils/common/UtilExceptions.h>2930#ifndef M_PI31#define M_PI 3.141592653589793238462643383279532#endif3334#define DEG2RAD(x) static_cast<double>((x) * M_PI / 180.)35#define RAD2DEG(x) static_cast<double>((x) * 180. / M_PI)36#define GRAVITY 9.80665373839// ===========================================================================40// class definitions41// ===========================================================================42/** @class GeomHelper43* @brief Some static methods performing geometrical operations44*/45class GeomHelper {4647public:48/// @brief a value to signify offsets outside the range of [0, Line.length()]49static const double INVALID_OFFSET;5051/** @brief Returns the positions the given circle is crossed by the given line52* @param[in] c The center position of the circle53* @param[in] radius The radius of the circle54* @param[in] p1 The begin of the line55* @param[in] p2 The end of the line56* @param[filled] into The list of crossing positions (0-1 along the line's length)57* @see http://blog.csharphelper.com/2010/03/28/determine-where-a-line-intersects-a-circle-in-c.aspx58* @see http://gamedev.stackexchange.com/questions/18333/circle-line-collision-detection-problem (jazzdawg)59*/60static void findLineCircleIntersections(const Position& c, double radius, const Position& p1, const Position& p2,61std::vector<double>& into);626364/** @brief Returns the angle between two vectors on a plane65The angle is from vector 1 to vector 2, positive anticlockwise66The result is between -pi and pi67*/68static double angle2D(const Position& p1, const Position& p2);6970static double nearest_offset_on_line_to_point2D(71const Position& lineStart, const Position& lineEnd,72const Position& p, bool perpendicular = true);7374static double nearest_offset_on_line_to_point25D(75const Position& lineStart, const Position& lineEnd,76const Position& p, bool perpendicular = true);7778static Position crossPoint(const Boundary& b,79const PositionVector& v);8081/** @brief Returns the distance of second angle from first angle counter-clockwise82* @param[in] angle1 The first angle83* @param[in] angle2 The second angle84* @return Angle (counter-clockwise) starting from first to second angle85*/86static double getCCWAngleDiff(double angle1, double angle2);878889/** @brief Returns the distance of second angle from first angle clockwise90* @param[in] angle1 The first angle91* @param[in] angle2 The second angle92* @return Angle (clockwise) starting from first to second angle93*/94static double getCWAngleDiff(double angle1, double angle2);959697/** @brief Returns the minimum distance (clockwise/counter-clockwise) between both angles98* @param[in] angle1 The first angle99* @param[in] angle2 The second angle100* @return The minimum distance between both angles101*/102static double getMinAngleDiff(double angle1, double angle2);103104105/** @brief Returns the difference of the second angle to the first angle in radiants106*107* The results are always between -pi and pi.108* Positive values denote that the second angle is counter clockwise closer, negative values mean109* it is clockwise closer.110* @param[in] angle1 The first angle111* @param[in] angle2 The second angle112* @return angle starting from first to second angle113*/114static double angleDiff(const double angle1, const double angle2);115116117/** Converts an angle from mathematical radians where 0 is to the right and positive angles118* are counterclockwise to navigational degrees where 0 is up and positive means clockwise.119* The result is always in the range [0, 360).120* @param[in] angle The angle in radians to convert121* @return the angle in degrees122*/123static double naviDegree(const double angle);124125/** Converts an angle from navigational degrees to mathematical radians.126* @see naviDegree127* @param[in] angle The angle in degree to convert128* @return the angle in radians129*/130static double fromNaviDegree(const double angle);131132/** Converts an angle from mathematical radians where 0 is to the right and positive angles133* are counterclockwise to the legacy degrees used in sumo where 0 is down and positive means clockwise.134* If positive is true the result is in the range [0, 360), otherwise in the range [-180, 180).135* @param[in] angle The angle in radians to convert136* @return the angle in degrees137*/138static double legacyDegree(const double angle, const bool positive = false);139140/** Creates a circular polygon141* @param[in] radius Radius of the circle142* @param[in] center Position of the circle's center143* @param[in] nPoints Number of points of the circle (Polygon's shape will have noPoints+1 points), must be >=3144* @return the polygon approximating the circle145*/146static PositionVector makeCircle(const double radius, const Position& center, unsigned int nPoints);147148/** Creates a circular polygon149* @param[in] radius1 Inner radius of the ring150* @param[in] radius2 Outer radius of the ring151* @param[in] center Position of the circle's center152* @param[in] nPoints Number of points of the circle (Polygon's shape will have noPoints+1 points), must be >=3153* @return the polygon approximating the circle154*/155static PositionVector makeRing(const double radius1, const double radius2, const Position& center, unsigned int nPoints);156157/// @brief calculate lotSpace position158static const Position calculateLotSpacePosition(const PositionVector& shape, const int index,159const double spaceDim, const double angle, const double width, const double length);160161/// @brief calculate lotSpace angle162static double calculateLotSpaceAngle(const PositionVector& shape, const int index, const double spaceDim, const double angle);163164/// @brief calculate lotSpace slope165static double calculateLotSpaceSlope(const PositionVector& shape, const int index, const double spaceDim);166};167168169