| 142 | } |
| 143 | |
| 144 | std::vector<ArrowBorders> CalculateArrowBorders(m2::RectD screenRect, double screenScale, float currentHalfWidth, |
| 145 | SubrouteConstPtr const & subroute, double subrouteLength, |
| 146 | double distanceFromBegin) |
| 147 | { |
| 148 | auto const & turns = subroute->m_turns; |
| 149 | if (turns.empty()) |
| 150 | return {}; |
| 151 | |
| 152 | // Calculate arrow mercator length. |
| 153 | double glbHalfLen = 0.5 * kArrowSize; |
| 154 | double const glbHalfTextureWidth = currentHalfWidth * kArrowHeightFactor * screenScale; |
| 155 | double const glbHalfTextureLen = glbHalfTextureWidth * kArrowAspect; |
| 156 | if (glbHalfLen < glbHalfTextureLen) |
| 157 | glbHalfLen = glbHalfTextureLen; |
| 158 | |
| 159 | double const glbArrowHead = 2.0 * kArrowHeadSize * glbHalfTextureLen; |
| 160 | double const glbArrowTail = 2.0 * kArrowTailSize * glbHalfTextureLen; |
| 161 | double const glbMinArrowSize = glbArrowHead + glbArrowTail; |
| 162 | |
| 163 | double constexpr kExtentCoef = 1.1; |
| 164 | screenRect.Scale(kExtentCoef); |
| 165 | |
| 166 | // Calculate arrow borders. |
| 167 | size_t constexpr kAverageArrowsCount = 10; |
| 168 | std::vector<ArrowBorders> newArrowBorders; |
| 169 | newArrowBorders.reserve(kAverageArrowsCount); |
| 170 | auto const & polyline = subroute->m_polyline; |
| 171 | for (size_t i = 0; i < turns.size(); i++) |
| 172 | { |
| 173 | ArrowBorders arrowBorders; |
| 174 | arrowBorders.m_groupIndex = static_cast<int>(i); |
| 175 | arrowBorders.m_startDistance = std::max(0.0, turns[i] - glbHalfLen * 0.8); |
| 176 | arrowBorders.m_endDistance = std::min(subrouteLength, turns[i] + glbHalfLen * 1.2); |
| 177 | |
| 178 | if ((arrowBorders.m_endDistance - arrowBorders.m_startDistance) < glbMinArrowSize || |
| 179 | arrowBorders.m_startDistance < distanceFromBegin) |
| 180 | { |
| 181 | continue; |
| 182 | } |
| 183 | |
| 184 | m2::PointD pt = polyline.GetPointByDistance(arrowBorders.m_startDistance); |
| 185 | if (screenRect.IsPointInside(pt)) |
| 186 | { |
| 187 | newArrowBorders.push_back(arrowBorders); |
| 188 | continue; |
| 189 | } |
| 190 | |
| 191 | pt = polyline.GetPointByDistance(arrowBorders.m_endDistance); |
| 192 | if (screenRect.IsPointInside(pt)) |
| 193 | { |
| 194 | newArrowBorders.push_back(arrowBorders); |
| 195 | continue; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | // Merge intersected borders and clip them. |
| 200 | MergeAndClipBorders(newArrowBorders); |
| 201 |
no test coverage detected