LCOV - code coverage report
Current view: top level - src/utils/gui/div - GUIGeometry.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 9.1 % 242 22
Test Date: 2024-12-21 15:45:41 Functions: 25.9 % 27 7

            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    GUIGeometry.cpp
      15              : /// @author  Pablo Alvarez Lopez
      16              : /// @date    Oct 2020
      17              : ///
      18              : // File for geometry classes and functions
      19              : /****************************************************************************/
      20              : #include <utils/geom/GeomHelper.h>
      21              : #include <utils/gui/div/GLHelper.h>
      22              : #include <utils/gui/globjects/GLIncludes.h>
      23              : #include <utils/gui/globjects/GUIGlObjectTypes.h>
      24              : #include <utils/gui/div/GUIGlobalViewObjectsHandler.h>
      25              : 
      26              : #include "GUIGeometry.h"
      27              : 
      28              : #define CIRCLE_RESOLUTION (double)10 // inverse in degrees
      29              : 
      30              : // ===========================================================================
      31              : // static member definitions
      32              : // ===========================================================================
      33              : PositionVector GUIGeometry::myCircleCoords;
      34              : 
      35              : // ===========================================================================
      36              : // method definitions
      37              : // ===========================================================================
      38              : 
      39            0 : GUIGeometry::GUIGeometry() {
      40            0 : }
      41              : 
      42              : 
      43        51126 : GUIGeometry::GUIGeometry(const PositionVector& shape) :
      44              :     myShape(shape) {
      45              :     // calculate shape rotation and lengths
      46        25563 :     calculateShapeRotationsAndLengths();
      47        25563 : }
      48              : 
      49              : 
      50            0 : GUIGeometry::GUIGeometry(const PositionVector& shape, const std::vector<double>& shapeRotations,
      51            0 :                          const std::vector<double>& shapeLengths) :
      52              :     myShape(shape),
      53            0 :     myShapeRotations(shapeRotations),
      54            0 :     myShapeLengths(shapeLengths) {
      55            0 : }
      56              : 
      57              : 
      58              : void
      59            0 : GUIGeometry::updateGeometry(const PositionVector& shape) {
      60              :     // clear geometry
      61            0 :     clearGeometry();
      62              :     // update shape
      63              :     myShape = shape;
      64              :     // calculate shape rotation and lengths
      65            0 :     calculateShapeRotationsAndLengths();
      66            0 : }
      67              : 
      68              : 
      69              : void
      70            0 : GUIGeometry::updateGeometry(const PositionVector& shape, const double posOverShape,
      71              :                             const double lateralOffset) {
      72              :     // first clear geometry
      73            0 :     clearGeometry();
      74              :     // get shape length
      75            0 :     const double shapeLength = shape.length();
      76              :     // calculate position and rotation
      77            0 :     if (posOverShape < 0) {
      78            0 :         myShape.push_back(shape.positionAtOffset(0, lateralOffset));
      79            0 :         myShapeRotations.push_back(shape.rotationDegreeAtOffset(0));
      80            0 :     } else if (posOverShape > shapeLength) {
      81            0 :         myShape.push_back(shape.positionAtOffset(shapeLength, lateralOffset));
      82            0 :         myShapeRotations.push_back(shape.rotationDegreeAtOffset(shapeLength));
      83              :     } else {
      84            0 :         myShape.push_back(shape.positionAtOffset(posOverShape, lateralOffset));
      85            0 :         myShapeRotations.push_back(shape.rotationDegreeAtOffset(posOverShape));
      86              :     }
      87            0 : }
      88              : 
      89              : 
      90              : void
      91            0 : GUIGeometry::updateGeometry(const PositionVector& shape, double starPosOverShape,
      92              :                             double endPosOverShape, const double lateralOffset) {
      93              :     // first clear geometry
      94            0 :     clearGeometry();
      95              :     // set new shape
      96              :     myShape = shape;
      97              :     // set lateral offset
      98            0 :     myShape.move2side(lateralOffset);
      99              :     // get shape length
     100            0 :     const double shapeLength = myShape.length2D();
     101              :     // set initial beginTrim value
     102            0 :     if (starPosOverShape < 0) {
     103              :         endPosOverShape = 0;
     104              :     }
     105              :     // set initial endtrim value
     106              :     if (starPosOverShape < 0) {
     107              :         endPosOverShape = shapeLength;
     108              :     }
     109              :     // check maximum beginTrim
     110            0 :     if (starPosOverShape > (shapeLength - POSITION_EPS)) {
     111              :         endPosOverShape = (shapeLength - POSITION_EPS);
     112              :     }
     113              :     // check maximum endTrim
     114            0 :     if ((endPosOverShape > shapeLength)) {
     115              :         endPosOverShape = shapeLength;
     116              :     }
     117              :     // check sub-vector
     118            0 :     if (endPosOverShape <= starPosOverShape) {
     119            0 :         endPosOverShape = endPosOverShape + POSITION_EPS;
     120              :     }
     121              :     // trim shape
     122            0 :     myShape = myShape.getSubpart2D(starPosOverShape, endPosOverShape);
     123              :     // calculate shape rotation and lengths
     124            0 :     calculateShapeRotationsAndLengths();
     125            0 : }
     126              : 
     127              : 
     128              : void
     129            0 : GUIGeometry::updateGeometry(const PositionVector& shape, double beginTrimPosition, const Position& extraFirstPosition,
     130              :                             double endTrimPosition, const Position& extraLastPosition) {
     131              :     // first clear geometry
     132            0 :     clearGeometry();
     133              :     // set new shape
     134              :     myShape = shape;
     135              :     // check trim values
     136            0 :     if ((beginTrimPosition != -1) || (endTrimPosition != -1)) {
     137              :         // get shape length
     138            0 :         const double shapeLength = myShape.length2D();
     139              :         // set initial beginTrim value
     140            0 :         if (beginTrimPosition < 0) {
     141              :             beginTrimPosition = 0;
     142              :         }
     143              :         // set initial endtrim value
     144            0 :         if (endTrimPosition < 0) {
     145              :             endTrimPosition = shapeLength;
     146              :         }
     147              :         // check maximum beginTrim
     148            0 :         if (beginTrimPosition > (shapeLength - POSITION_EPS)) {
     149              :             beginTrimPosition = (shapeLength - POSITION_EPS);
     150              :         }
     151              :         // check maximum endTrim
     152            0 :         if ((endTrimPosition > shapeLength)) {
     153              :             endTrimPosition = shapeLength;
     154              :         }
     155              :         // check sub-vector
     156            0 :         if (endTrimPosition <= beginTrimPosition) {
     157            0 :             endTrimPosition = endTrimPosition + POSITION_EPS;
     158              :         }
     159              :         // trim shape
     160            0 :         myShape = myShape.getSubpart2D(beginTrimPosition, endTrimPosition);
     161              :         // add extra positions
     162              :         if (extraFirstPosition != Position::INVALID) {
     163            0 :             myShape.push_front_noDoublePos(extraFirstPosition);
     164              :         }
     165              :         if (extraLastPosition != Position::INVALID) {
     166            0 :             myShape.push_back_noDoublePos(extraLastPosition);
     167              :         }
     168              :     }
     169              :     // calculate shape rotation and lengths
     170            0 :     calculateShapeRotationsAndLengths();
     171            0 : }
     172              : 
     173              : 
     174              : void
     175            0 : GUIGeometry::updateSinglePosGeometry(const Position& position, const double rotation) {
     176              :     // first clear geometry
     177            0 :     clearGeometry();
     178              :     // set position and rotation
     179            0 :     myShape.push_back(position);
     180            0 :     myShapeRotations.push_back(rotation);
     181            0 : }
     182              : 
     183              : 
     184            0 : void GUIGeometry::clearGeometry() {
     185              :     // clear geometry containers
     186              :     myShape.clear();
     187              :     myShapeRotations.clear();
     188              :     myShapeLengths.clear();
     189            0 : }
     190              : 
     191              : 
     192              : void
     193            0 : GUIGeometry::moveGeometryToSide(const double amount) {
     194              :     // move shape
     195            0 :     myShape.move2side(amount);
     196            0 : }
     197              : 
     198              : 
     199              : void
     200            0 : GUIGeometry::scaleGeometry(const double scale) {
     201              :     // scale shape and lengths
     202            0 :     myShape.scaleRelative(scale);
     203              :     // scale lengths
     204            0 :     for (auto& shapeLength : myShapeLengths) {
     205            0 :         shapeLength *= scale;
     206              :     }
     207            0 : }
     208              : 
     209              : 
     210              : const PositionVector&
     211        25563 : GUIGeometry::getShape() const {
     212        25563 :     return myShape;
     213              : }
     214              : 
     215              : 
     216              : const std::vector<double>&
     217        25563 : GUIGeometry::getShapeRotations() const {
     218        25563 :     return myShapeRotations;
     219              : }
     220              : 
     221              : 
     222              : const std::vector<double>&
     223        25563 : GUIGeometry::getShapeLengths() const {
     224        25563 :     return myShapeLengths;
     225              : }
     226              : 
     227              : 
     228              : double
     229        87242 : GUIGeometry::calculateRotation(const Position& first, const Position& second) {
     230              :     // return rotation (angle) of the vector constructed by points first and second
     231        87242 :     return ((double)atan2((second.x() - first.x()), (first.y() - second.y())) * (double) 180.0 / (double)M_PI);
     232              : }
     233              : 
     234              : 
     235              : double
     236        87242 : GUIGeometry::calculateLength(const Position& first, const Position& second) {
     237              :     // return 2D distance between two points
     238        87242 :     return first.distanceTo2D(second);
     239              : }
     240              : 
     241              : 
     242              : void
     243            0 : GUIGeometry::adjustStartPosGeometricPath(double& startPos, const PositionVector& startLaneShape,
     244              :         double& endPos, const PositionVector& endLaneShape) {
     245              :     // adjust both, if start and end lane are the same
     246            0 :     if ((startLaneShape.size() > 0) &&
     247            0 :             (endLaneShape.size() > 0) &&
     248            0 :             (startLaneShape == endLaneShape) &&
     249            0 :             (startPos != -1) &&
     250            0 :             (endPos != -1)) {
     251            0 :         if (startPos >= endPos) {
     252            0 :             endPos = (startPos + POSITION_EPS);
     253              :         }
     254              :     }
     255              :     // adjust startPos
     256            0 :     if ((startPos != -1) && (startLaneShape.size() > 0)) {
     257            0 :         if (startPos < POSITION_EPS) {
     258            0 :             startPos = POSITION_EPS;
     259              :         }
     260            0 :         if (startPos > (startLaneShape.length() - POSITION_EPS)) {
     261            0 :             startPos = (startLaneShape.length() - POSITION_EPS);
     262              :         }
     263              :     }
     264              :     // adjust endPos
     265            0 :     if ((endPos != -1) && (endLaneShape.size() > 0)) {
     266            0 :         if (endPos < POSITION_EPS) {
     267            0 :             endPos = POSITION_EPS;
     268              :         }
     269            0 :         if (endPos > (endLaneShape.length() - POSITION_EPS)) {
     270            0 :             endPos = (endLaneShape.length() - POSITION_EPS);
     271              :         }
     272              :     }
     273            0 : }
     274              : 
     275              : 
     276              : void
     277            0 : GUIGeometry::drawGeometry(const GUIVisualizationSettings::Detail d, const GUIGeometry& geometry,
     278              :                           const double width, double offset) {
     279              :     // continue depending of detail level
     280            0 :     if (d <= GUIVisualizationSettings::Detail::GeometryBoxLines) {
     281            0 :         GLHelper::drawBoxLines(geometry.getShape(), geometry.getShapeRotations(), geometry.getShapeLengths(), width, 0, offset);
     282            0 :     } else if (d < GUIVisualizationSettings::Detail::GeometryBoxSimpleLine) {
     283              :         // set line width
     284            0 :         glLineWidth(static_cast<float>(width));
     285              :         // draw a simple line
     286            0 :         GLHelper::drawLine(geometry.getShape());
     287              :         // restore line width
     288            0 :         glLineWidth(1);
     289              :     } else {
     290              :         // draw a simple line
     291            0 :         GLHelper::drawLine(geometry.getShape());
     292              :     }
     293            0 : }
     294              : 
     295              : 
     296              : void
     297            0 : GUIGeometry::drawGeometry(const GUIVisualizationSettings::Detail d, const GUIGeometry& geometry,
     298              :                           const std::vector<RGBColor>& colors, const double width, double offset) {
     299              :     // continue depending of detail level
     300            0 :     if (d <= GUIVisualizationSettings::Detail::GeometryBoxLines) {
     301            0 :         GLHelper::drawBoxLines(geometry.getShape(), geometry.getShapeRotations(), geometry.getShapeLengths(), colors, width, 0, offset);
     302              :     } else {
     303              :         // set first color
     304            0 :         GLHelper::setColor(*colors.begin());
     305              :         // set width
     306            0 :         if (d < GUIVisualizationSettings::Detail::GeometryBoxSimpleLine) {
     307              :             // set line width
     308            0 :             glLineWidth(static_cast<float>(width));
     309              :             // draw a simple line
     310            0 :             GLHelper::drawLine(geometry.getShape());
     311              :             // restore line width
     312            0 :             glLineWidth(1);
     313              :         } else {
     314              :             // draw a simple line
     315            0 :             GLHelper::drawLine(geometry.getShape());
     316              :         }
     317              :     }
     318            0 : }
     319              : 
     320              : 
     321              : void
     322            0 : GUIGeometry::drawContourGeometry(const GUIGeometry& geometry, const double width, const bool drawExtremes) {
     323              :     // get shapes
     324            0 :     PositionVector shapeA = geometry.getShape();
     325            0 :     PositionVector shapeB = geometry.getShape();
     326              :     // move both shapes
     327            0 :     shapeA.move2side((width - 0.1));
     328            0 :     shapeB.move2side((width - 0.1) * -1);
     329              :     // check if we have to drawn extremes
     330            0 :     if (drawExtremes) {
     331              :         // reverse shape B
     332            0 :         shapeB = shapeB.reverse();
     333              :         // append shape B to shape A
     334            0 :         shapeA.append(shapeB, 0);
     335              :         // close shape A
     336            0 :         shapeA.closePolygon();
     337              :         // draw box lines using shapeA
     338            0 :         GLHelper::drawBoxLines(shapeA, 0.1);
     339              :     } else {
     340              :         // draw box lines using shapeA
     341            0 :         GLHelper::drawBoxLines(shapeA, 0.1);
     342              :         // draw box lines using shapeA
     343            0 :         GLHelper::drawBoxLines(shapeB, 0.1);
     344              :     }
     345            0 : }
     346              : 
     347              : 
     348              : void
     349            0 : GUIGeometry::drawGeometryPoints(const GUIVisualizationSettings::Detail d, const PositionVector& shape,
     350              :                                 const RGBColor& color, const double radius, const double exaggeration,
     351              :                                 const bool editingElevation) {
     352              :     // check detail level
     353            0 :     if (d <= GUIVisualizationSettings::Detail::GeometryPoint) {
     354              :         // get exaggeratedRadio
     355            0 :         const double exaggeratedRadio = (radius * exaggeration);
     356              :         // iterate over geometryPoints
     357            0 :         for (const auto& geometryPos : shape) {
     358              :             // push geometry point matrix
     359            0 :             GLHelper::pushMatrix();
     360              :             // move to vertex
     361            0 :             glTranslated(geometryPos.x(), geometryPos.y(), 0.2);
     362              :             // set color
     363            0 :             GLHelper::setColor(color);
     364              :             // draw circle detailled
     365            0 :             GLHelper::drawFilledCircleDetailled(d, exaggeratedRadio);
     366              :             // pop geometry point matrix
     367            0 :             GLHelper::popMatrix();
     368              :             // draw elevation or special symbols (Start, End and Block)
     369            0 :             if (d <= GUIVisualizationSettings::Detail::Text) {
     370            0 :                 if (editingElevation) {
     371              :                     // Push Z matrix
     372            0 :                     GLHelper::pushMatrix();
     373              :                     // draw Z (elevation)
     374            0 :                     GLHelper::drawText(toString(geometryPos.z()), geometryPos, 0.3, 0.7, color.invertedColor());
     375              :                     // pop Z matrix
     376            0 :                     GLHelper::popMatrix();
     377              :                 } else if (geometryPos == shape.front()) {
     378              :                     // push "S" matrix
     379            0 :                     GLHelper::pushMatrix();
     380              :                     // draw a "s" over first point
     381            0 :                     GLHelper::drawText("S", geometryPos, 0.3, 2 * exaggeratedRadio, color.invertedColor());
     382              :                     // pop "S" matrix
     383            0 :                     GLHelper::popMatrix();
     384              :                 } else if (geometryPos == shape.back()) {
     385              :                     // push "E" matrix
     386            0 :                     GLHelper::pushMatrix();
     387              :                     // draw a "e" over last point if polygon isn't closed
     388            0 :                     GLHelper::drawText("E", geometryPos, 0.3, 2 * exaggeratedRadio, color.invertedColor());
     389              :                     // pop "E" matrix
     390            0 :                     GLHelper::popMatrix();
     391              :                 }
     392              :             }
     393              :         }
     394              :     }
     395            0 : }
     396              : 
     397              : 
     398              : void
     399            0 : GUIGeometry::drawParentLine(const GUIVisualizationSettings& s, const Position& parent, const Position& child,
     400              :                             const RGBColor& color, const bool drawEntire, const double lineWidth) {
     401            0 :     if (!s.drawForRectangleSelection) {
     402              :         // calculate rotation
     403            0 :         const double rot = RAD2DEG(parent.angleTo2D(child)) + 90;
     404              :         // calculate distance between origin and destination
     405              :         const double distanceSquared = parent.distanceSquaredTo2D(child);
     406              :         // Add a draw matrix for details
     407            0 :         GLHelper::pushMatrix();
     408              :         // move back
     409            0 :         glTranslated(0, 0, -1);
     410              :         // draw box line
     411            0 :         if (drawEntire) {
     412              :             // draw first box line
     413            0 :             GLHelper::setColor(color.changedBrightness(-50));
     414            0 :             GLHelper::drawBoxLine(parent, rot, sqrt(distanceSquared), lineWidth);
     415              :             // move front
     416            0 :             glTranslated(0, 0, 0.1);
     417              :             // draw second box line
     418            0 :             GLHelper::setColor(color);
     419            0 :             GLHelper::drawBoxLine(parent, rot, sqrt(distanceSquared), .04);
     420            0 :         } else if (distanceSquared > 25) {
     421              :             // draw first box line with length 4.9
     422            0 :             GLHelper::setColor(color.changedBrightness(-50));
     423            0 :             GLHelper::drawBoxLine(parent, rot, 4.9, lineWidth);
     424            0 :             glTranslated(0, 0, 0.1);
     425              :             // draw second box line with length 4.9
     426            0 :             GLHelper::setColor(color);
     427            0 :             GLHelper::drawBoxLine(parent, rot, 4.9, .04);
     428              :             // draw arrow depending of distanceSquared (10*10)
     429            0 :             if (distanceSquared > 100) {
     430              :                 // calculate positionVector between both points
     431            0 :                 const PositionVector vector = {parent, child};
     432              :                 // draw first arrow at end
     433            0 :                 GLHelper::setColor(color.changedBrightness(-50));
     434            0 :                 GLHelper::drawTriangleAtEnd(parent,
     435            0 :                                             vector.positionAtOffset2D(5),
     436              :                                             s.additionalSettings.arrowWidth,
     437              :                                             s.additionalSettings.arrowLength,
     438              :                                             s.additionalSettings.arrowOffset);
     439              :                 // move front
     440            0 :                 glTranslated(0, 0, 0.1);
     441              :                 // draw second arrow at end
     442            0 :                 GLHelper::setColor(color);
     443            0 :                 GLHelper::drawTriangleAtEnd(parent,
     444            0 :                                             vector.positionAtOffset2D(5),
     445              :                                             s.additionalSettings.arrowWidth - 0.01,
     446              :                                             s.additionalSettings.arrowLength - 0.01,
     447              :                                             s.additionalSettings.arrowOffset - 0.01);
     448            0 :             }
     449              :         }
     450              :         // pop draw matrix
     451            0 :         GLHelper::popMatrix();
     452              :     }
     453            0 : }
     454              : 
     455              : 
     456              : void
     457            0 : GUIGeometry::drawChildLine(const GUIVisualizationSettings& s, const Position& child, const Position& parent,
     458              :                            const RGBColor& color, const bool drawEntire, const double lineWidth) {
     459            0 :     if (!s.drawForRectangleSelection) {
     460              :         // calculate distance between origin and destination
     461              :         const double distanceSquared = child.distanceSquaredTo2D(parent);
     462              :         // calculate subline width
     463            0 :         const double sublineWidth = (lineWidth * 0.8);
     464              :         // calculate rotation
     465            0 :         const double rot = RAD2DEG(child.angleTo2D(parent)) + 90;
     466              :         // Add a draw matrix for details
     467            0 :         GLHelper::pushMatrix();
     468              :         // move back
     469            0 :         glTranslated(0, 0, -1);
     470              :         // set color
     471            0 :         GLHelper::setColor(color);
     472              :         // draw box line
     473            0 :         if (drawEntire || (distanceSquared < 25)) {
     474              :             // set color
     475            0 :             GLHelper::setColor(color);
     476              :             // draw first box line
     477            0 :             GLHelper::setColor(color.changedBrightness(-50));
     478            0 :             GLHelper::drawBoxLine(child, rot, sqrt(distanceSquared), lineWidth);
     479              :             // move front
     480            0 :             glTranslated(0, 0, 0.1);
     481              :             // draw second box line
     482            0 :             GLHelper::setColor(color);
     483            0 :             GLHelper::drawBoxLine(child, rot, sqrt(distanceSquared), sublineWidth);
     484              :         } else {
     485              :             // draw first box line with length 4.9
     486            0 :             GLHelper::setColor(color.changedBrightness(-50));
     487            0 :             GLHelper::drawBoxLine(child, rot, 4.9, lineWidth);
     488            0 :             glTranslated(0, 0, 0.1);
     489              :             // draw second box line with length
     490            0 :             GLHelper::setColor(color);
     491            0 :             GLHelper::drawBoxLine(child, rot, 4.9, sublineWidth);
     492              :             // draw arrow depending of distanceSquared (10*10)
     493            0 :             if (distanceSquared > 100) {
     494              :                 // calculate positionVector between both points
     495            0 :                 const PositionVector vector = {child, parent};
     496              :                 // draw first arrow at end
     497            0 :                 GLHelper::setColor(color.changedBrightness(-50));
     498            0 :                 GLHelper::drawTriangleAtEnd(child,
     499            0 :                                             vector.positionAtOffset2D(5),
     500              :                                             s.additionalSettings.arrowWidth,
     501              :                                             s.additionalSettings.arrowLength,
     502              :                                             s.additionalSettings.arrowOffset);
     503              :                 // move front
     504            0 :                 glTranslated(0, 0, 0.1);
     505              :                 // draw second arrow at end
     506            0 :                 GLHelper::setColor(color);
     507            0 :                 GLHelper::drawTriangleAtEnd(child,
     508            0 :                                             vector.positionAtOffset2D(5),
     509              :                                             s.additionalSettings.arrowWidth - 0.01,
     510              :                                             s.additionalSettings.arrowLength - 0.01,
     511              :                                             s.additionalSettings.arrowOffset - 0.01);
     512            0 :             }
     513              :         }
     514              :         // pop draw matrix
     515            0 :         GLHelper::popMatrix();
     516              :     }
     517            0 : }
     518              : 
     519              : 
     520              : PositionVector
     521            0 : GUIGeometry::getVertexCircleAroundPosition(const Position& pos, const double width, const int steps) {
     522              :     // first check if we have to fill myCircleCoords (only once)
     523            0 :     if (myCircleCoords.size() == 0) {
     524            0 :         for (int i = 0; i <= (int)(360 * CIRCLE_RESOLUTION); ++i) {
     525            0 :             const double x = (double) sin(DEG2RAD(i / CIRCLE_RESOLUTION));
     526            0 :             const double y = (double) cos(DEG2RAD(i / CIRCLE_RESOLUTION));
     527            0 :             myCircleCoords.push_back(Position(x, y));
     528              :         }
     529              :     }
     530            0 :     PositionVector vertexCircle;
     531            0 :     const double inc = 360 / (double)steps;
     532              :     // obtain all vertices
     533            0 :     for (int i = 0; i <= steps; ++i) {
     534            0 :         const Position& vertex = myCircleCoords[GUIGeometry::angleLookup(i * inc)];
     535            0 :         vertexCircle.push_back(Position(vertex.x() * width, vertex.y() * width));
     536              :     }
     537              :     // move result using position
     538            0 :     vertexCircle.add(pos);
     539            0 :     return vertexCircle;
     540            0 : }
     541              : 
     542              : 
     543              : void
     544            0 : GUIGeometry::rotateOverLane(const double rot) {
     545              :     // rotate using rotation calculated in PositionVector
     546            0 :     glRotated((rot * -1) + 90, 0, 0, 1);
     547            0 : }
     548              : 
     549              : 
     550              : int
     551            0 : GUIGeometry::angleLookup(const double angleDeg) {
     552            0 :     const int numCoords = (int)myCircleCoords.size() - 1;
     553            0 :     int index = ((int)(floor(angleDeg * CIRCLE_RESOLUTION + 0.5))) % numCoords;
     554            0 :     if (index < 0) {
     555            0 :         index += numCoords;
     556              :     }
     557              :     assert(index >= 0);
     558            0 :     return (int)index;
     559              : }
     560              : 
     561              : 
     562              : void
     563        25563 : GUIGeometry::calculateShapeRotationsAndLengths() {
     564              :     // clear rotations and lengths
     565              :     myShapeRotations.clear();
     566              :     myShapeLengths.clear();
     567              :     // Get number of parts of the shape
     568        25563 :     int numberOfSegments = (int)myShape.size() - 1;
     569              :     // If number of segments is more than 0
     570        25563 :     if (numberOfSegments >= 0) {
     571              :         // Reserve memory (To improve efficiency)
     572        25563 :         myShapeRotations.reserve(numberOfSegments);
     573        25563 :         myShapeLengths.reserve(numberOfSegments);
     574              :         // Calculate lengths and rotations for every shape
     575       112805 :         for (int i = 0; i < numberOfSegments; i++) {
     576        87242 :             myShapeRotations.push_back(calculateRotation(myShape[i], myShape[i + 1]));
     577        87242 :             myShapeLengths.push_back(calculateLength(myShape[i], myShape[i + 1]));
     578              :         }
     579              :     }
     580        25563 : }
     581              : 
     582              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1