From f16a25a276fffec4a335656b39ee9fb416a0dd5e Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Fri, 28 Aug 2015 14:46:31 +0300 Subject: [PATCH] Added heuristic algorithm to find invalid for route data --- drape_frontend/line_shape_helper.cpp | 45 ++++++++++++++++++---------- drape_frontend/line_shape_helper.hpp | 2 ++ drape_frontend/route_renderer.cpp | 2 +- drape_frontend/route_shape.cpp | 2 +- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/drape_frontend/line_shape_helper.cpp b/drape_frontend/line_shape_helper.cpp index afa3e574ef..5244a73c75 100644 --- a/drape_frontend/line_shape_helper.cpp +++ b/drape_frontend/line_shape_helper.cpp @@ -17,14 +17,15 @@ void UpdateNormalBetweenSegments(LineSegment * segment1, LineSegment * segment2) float const dotProduct = glsl::dot(segment1->m_leftNormals[EndPoint], segment2->m_leftNormals[StartPoint]); float const absDotProduct = fabs(dotProduct); - float const eps = 1e-5; + float const kEps = 1e-5; - if (fabs(absDotProduct - 1.0f) < eps) + if (fabs(absDotProduct - 1.0f) < kEps) { // change nothing return; } + float const kMaxScalar = 5; float const crossProduct = glsl::cross(glsl::vec3(segment1->m_tangent, 0), glsl::vec3(segment2->m_tangent, 0)).z; if (crossProduct < 0) @@ -35,13 +36,20 @@ void UpdateNormalBetweenSegments(LineSegment * segment1, LineSegment * segment2) // change right-side normals glsl::vec2 averageNormal = glsl::normalize(segment1->m_rightNormals[EndPoint] + segment2->m_rightNormals[StartPoint]); - segment1->m_rightNormals[EndPoint] = averageNormal; - segment2->m_rightNormals[StartPoint] = averageNormal; - float const cosAngle = glsl::dot(segment1->m_tangent, averageNormal); - segment1->m_rightWidthScalar[EndPoint].x = 1.0f / sqrt(1.0f - cosAngle * cosAngle); - segment1->m_rightWidthScalar[EndPoint].y = segment1->m_rightWidthScalar[EndPoint].x * cosAngle; - segment2->m_rightWidthScalar[StartPoint] = segment1->m_rightWidthScalar[EndPoint]; + float const widthScalar = 1.0f / sqrt(1.0f - cosAngle * cosAngle); + if (widthScalar < kMaxScalar) + { + segment1->m_rightNormals[EndPoint] = averageNormal; + segment2->m_rightNormals[StartPoint] = averageNormal; + segment1->m_rightWidthScalar[EndPoint].x = widthScalar; + segment1->m_rightWidthScalar[EndPoint].y = widthScalar * cosAngle; + segment2->m_rightWidthScalar[StartPoint] = segment1->m_rightWidthScalar[EndPoint]; + } + else + { + segment1->m_generateJoin = false; + } } else { @@ -51,13 +59,20 @@ void UpdateNormalBetweenSegments(LineSegment * segment1, LineSegment * segment2) // change left-side normals glsl::vec2 averageNormal = glsl::normalize(segment1->m_leftNormals[EndPoint] + segment2->m_leftNormals[StartPoint]); - segment1->m_leftNormals[EndPoint] = averageNormal; - segment2->m_leftNormals[StartPoint] = averageNormal; - float const cosAngle = glsl::dot(segment1->m_tangent, averageNormal); - segment1->m_leftWidthScalar[EndPoint].x = 1.0f / sqrt(1.0f - cosAngle * cosAngle); - segment1->m_leftWidthScalar[EndPoint].y = segment1->m_leftWidthScalar[EndPoint].x * cosAngle; - segment2->m_leftWidthScalar[StartPoint] = segment1->m_leftWidthScalar[EndPoint]; + float const widthScalar = 1.0f / sqrt(1.0f - cosAngle * cosAngle); + if (widthScalar < kMaxScalar) + { + segment1->m_leftNormals[EndPoint] = averageNormal; + segment2->m_leftNormals[StartPoint] = averageNormal; + segment1->m_leftWidthScalar[EndPoint].x = widthScalar; + segment1->m_leftWidthScalar[EndPoint].y = widthScalar * cosAngle; + segment2->m_leftWidthScalar[StartPoint] = segment1->m_leftWidthScalar[EndPoint]; + } + else + { + segment1->m_generateJoin = false; + } } } @@ -214,7 +229,7 @@ glsl::vec2 GetNormal(LineSegment const & segment, bool isLeft, ENormalType norma int const index = (normalType == StartNormal) ? StartPoint : EndPoint; return isLeft ? segment.m_leftWidthScalar[index].x * segment.m_leftNormals[index]: - segment.m_rightWidthScalar[index].x * segment.m_rightNormals[index]; + segment.m_rightWidthScalar[index].x * segment.m_rightNormals[index]; } float GetProjectionLength(glsl::vec2 const & newPoint, glsl::vec2 const & startPoint, diff --git a/drape_frontend/line_shape_helper.hpp b/drape_frontend/line_shape_helper.hpp index cac35994ca..9f16decf37 100644 --- a/drape_frontend/line_shape_helper.hpp +++ b/drape_frontend/line_shape_helper.hpp @@ -33,12 +33,14 @@ struct LineSegment glsl::vec2 m_leftWidthScalar[PointsCount]; glsl::vec2 m_rightWidthScalar[PointsCount]; bool m_hasLeftJoin[PointsCount]; + bool m_generateJoin; LineSegment() { m_leftWidthScalar[StartPoint] = m_leftWidthScalar[EndPoint] = glsl::vec2(1.0f, 0.0f); m_rightWidthScalar[StartPoint] = m_rightWidthScalar[EndPoint] = glsl::vec2(1.0f, 0.0f); m_hasLeftJoin[StartPoint] = m_hasLeftJoin[EndPoint] = true; + m_generateJoin = true; } }; diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index 169532e607..b2b0f4602e 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -106,7 +106,7 @@ void MergeAndClipBorders(vector & borders) } // merge groups - int lastGroup = 0; + int lastGroup = borders.front().m_groupIndex; size_t lastGroupIndex = 0; for (size_t i = 1; i < borders.size(); i++) { diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 884e15b6bd..8648414230 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -211,7 +211,7 @@ void RouteShape::PrepareGeometry(bool isRoute, vector const & path, geometry.push_back(RV(endPivot, glsl::vec2(0, 0), glsl::vec3(endLength, 0, kCenter))); // generate joins - if (i < segments.size() - 1) + if (segments[i].m_generateJoin && i < segments.size() - 1) { glsl::vec2 n1 = segments[i].m_hasLeftJoin[EndPoint] ? segments[i].m_leftNormals[EndPoint] : segments[i].m_rightNormals[EndPoint];