From ba7ce3eb086459fcebbc9ae8f1e88431249f4ba5 Mon Sep 17 00:00:00 2001 From: namdre Date: Sun, 20 Jun 2021 23:01:00 +0200 Subject: [PATCH] building shape for indirect left turn. refs #4252 --- src/netbuild/NBNode.cpp | 31 +++++++++++++++++++++++++++++++ src/netbuild/NBNode.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/src/netbuild/NBNode.cpp b/src/netbuild/NBNode.cpp index d1ad1fbbb0c..1543a401024 100644 --- a/src/netbuild/NBNode.cpp +++ b/src/netbuild/NBNode.cpp @@ -85,6 +85,7 @@ const int NBNode::AVOID_WIDE_RIGHT_TURN(2); const int NBNode::FOUR_CONTROL_POINTS(4); const int NBNode::AVOID_INTERSECTING_LEFT_TURNS(8); const int NBNode::SCURVE_IGNORE(16); +const int NBNode::INDIRECT_LEFT(32); // =========================================================================== // method definitions @@ -520,6 +521,9 @@ NBNode::computeSmoothShape(const PositionVector& begShape, int shapeFlag) const { bool ok = true; + if ((shapeFlag & INDIRECT_LEFT) != 0) { + return indirectLeftShape(begShape, endShape, numPoints); + } PositionVector init = bezierControlPoints(begShape, endShape, isTurnaround, extrapolateBeg, extrapolateEnd, ok, recordError, DEG2RAD(5), shapeFlag); #ifdef DEBUG_SMOOTH_GEOM if (DEBUGCOND) { @@ -700,6 +704,30 @@ NBNode::bezierControlPoints( return init; } +PositionVector +NBNode::indirectLeftShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints) const { + UNUSED_PARAMETER(numPoints); + PositionVector result; + result.push_back(begShape.back()); + //const double angle = GeomHelper::angleDiff(begShape.angleAt2D(-2), endShape.angleAt2D(0)); + PositionVector endShapeBegLine(endShape[0], endShape[1]); + PositionVector begShapeEndLineRev(begShape[-1], begShape[-2]); + endShapeBegLine.extrapolate2D(100, true); + begShapeEndLineRev.extrapolate2D(100, true); + Position intersect = endShapeBegLine.intersectionPosition2D(begShapeEndLineRev); + if (intersect == Position::INVALID) { + WRITE_WARNING("Could not compute indirect left turn shape at node '" + getID() + "'"); + } else { + Position dir = intersect; + dir.sub(endShape[0]); + dir.norm2d(); + const double radius = myRadius == NBNode::UNSPECIFIED_RADIUS ? OptionsCont::getOptions().getFloat("default.junctions.radius") : myRadius; + dir.mul(radius); + result.push_back(intersect + dir); + } + result.push_back(endShape.front()); + return result; +} PositionVector NBNode::computeInternalLaneShape(const NBEdge* fromE, const NBEdge::Connection& con, int numPoints, NBNode* recordError, int shapeFlag) const { @@ -760,6 +788,9 @@ NBNode::computeInternalLaneShape(const NBEdge* fromE, const NBEdge::Connection& if (dir == LinkDirection::LEFT || dir == LinkDirection::TURN) { shapeFlag += AVOID_WIDE_LEFT_TURN; } + if (con.indirectLeft) { + shapeFlag += INDIRECT_LEFT; + } #ifdef DEBUG_SMOOTH_GEOM if (DEBUGCOND) { std::cout << "computeInternalLaneShape node " << getID() << " fromE=" << fromE->getID() << " toE=" << con.toEdge->getID() << "\n"; diff --git a/src/netbuild/NBNode.h b/src/netbuild/NBNode.h index fb7de9dc780..e8ef94fa44e 100644 --- a/src/netbuild/NBNode.h +++ b/src/netbuild/NBNode.h @@ -213,6 +213,7 @@ class NBNode : public Named, public Parameterised { static const int FOUR_CONTROL_POINTS; static const int AVOID_INTERSECTING_LEFT_TURNS; static const int SCURVE_IGNORE; + static const int INDIRECT_LEFT; public: /**@brief Constructor @@ -607,6 +608,8 @@ class NBNode : public Named, public Parameterised { bool& ok, NBNode* recordError = 0, double straightThresh = DEG2RAD(5), int shapeFlag = 0); + /// @brief compute shape of indirect left turn + PositionVector indirectLeftShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints) const; /// @brief compute the displacement error during s-curve computation double getDisplacementError() const {