17 #include "ad/physics/MetricRange.hpp"
18 #include "ad/physics/Operation.hpp"
19 #include "ad/physics/ParametricRange.hpp"
20 #include "ad/physics/ParametricValueValidInputRange.hpp"
21 #include "ad/physics/RangeOperation.hpp"
43 template <
typename Po
intType>
46 PointType line = pt1 - pt0;
47 PointType pt02a = a - pt0;
49 if (physics::Distance(divisor) > physics::Distance(0))
52 auto result = dividend / divisor;
53 return physics::RatioValue(result);
57 return physics::RatioValue(0.5);
70 template <
typename Po
intType>
74 if (t < physics::RatioValue(0.))
76 return physics::ParametricValue(0.);
78 else if (t > physics::RatioValue(1.))
80 return physics::ParametricValue(1.);
84 return physics::ParametricValue(
static_cast<double>(t));
93 template <
typename Po
intType> physics::Distance
calculateEdgeLength(std::vector<PointType>
const &edge)
95 physics::Distance length(0.);
96 for (
auto i = 1u; i < edge.size(); ++i)
98 length +=
distance(edge[i - 1u], edge[i]);
108 template <
typename Po
intType>
111 std::vector<physics::ParametricValue> resultPoints;
112 resultPoints.reserve(edge.size());
113 resultPoints.push_back(physics::ParametricValue(0.));
114 physics::Distance length(0.);
115 for (
auto i = 1u; i < edge.size(); ++i)
117 length +=
distance(edge[i - 1u], edge[i]);
118 resultPoints.push_back(physics::ParametricValue(
static_cast<double>(length)));
121 for (
auto i = 1u; i < edge.size(); ++i)
123 if (length > physics::Distance(0.))
125 resultPoints[i] = resultPoints[i] /
static_cast<double>(length);
137 template <
typename Po
intType>
139 physics::Distance
const &edgeLength,
140 const physics::ParametricValue &t)
144 physics::Distance length(0);
145 physics::Distance length_t = edgeLength * t;
146 for (
size_t i = 0; i < edge.size() - 1; i++)
148 const auto &pt0 = edge[i];
149 const auto &pt1 = edge[i + 1];
151 if (d != physics::Distance(0.))
153 auto length_1 = length + d;
154 if (length_1 >= length_t)
156 auto d_t = length_t - length;
157 physics::ParametricValue tt(d_t / d);
180 template <
typename Po
intType>
192 template <
typename Po
intType>
194 physics::Distance
const &edgeLength,
195 const physics::ParametricRange &trange)
197 typedef std::vector<PointType> EdgeType;
201 physics::Distance length(0);
202 physics::Distance length_t_start = edgeLength * trange.minimum;
204 for (; i < edge.size() - 1 && pts.empty(); i++)
206 const PointType &pt0 = edge[i];
207 const PointType &pt1 = edge[i + 1];
208 physics::Distance d =
distance(pt0, pt1);
209 physics::Distance length_1 = length + d;
210 if (length_1 >= length_t_start)
212 if (d != physics::Distance(0))
214 physics::Distance d_t = length_t_start - length;
215 physics::ParametricValue tt(d_t / d);
217 pts.push_back(pt_start);
232 physics::Distance length_t_end = edgeLength * trange.maximum;
233 for (; i < edge.size() - 1; i++)
235 const PointType &pt0 = edge[i];
236 const PointType &pt1 = edge[i + 1];
237 physics::Distance d =
distance(pt0, pt1);
238 physics::Distance length_1 = length + d;
239 if (length_1 >= length_t_end)
241 if (d != physics::Distance(0))
243 physics::Distance d_t = length_t_end - length;
244 physics::ParametricValue tt(d_t / d);
246 pts.push_back(pt_end);
260 pts.push_back(edge.back());
273 template <
typename Po
intType>
274 std::vector<PointType>
getParametricRange(std::vector<PointType>
const &edge,
const physics::ParametricRange &trange)
285 template <
typename Po
intType>
286 physics::ParametricValue
291 if (edge.size() == 0)
293 return physics::ParametricValue();
295 else if ((edge.size() == 1) || (edgeLength == physics::Distance(0.)))
297 return physics::ParametricValue(0);
303 physics::Distance d_nearest =
distance(pt, pt_nearest);
304 physics::Distance offset_nearest =
distance(pt_nearest, edge[0]);
305 physics::Distance running_offset = physics::Distance(0);
306 for (
size_t i = 1; i + 1 < edge.size(); i++)
310 physics::Distance d =
distance(pt_candidate, pt);
311 running_offset +=
distance(edge[i - 1], edge[i]);
314 pt_nearest = pt_candidate;
316 offset_nearest = running_offset +
distance(pt_nearest, edge[i]);
319 return physics::ParametricValue(offset_nearest / edgeLength);
324 return physics::ParametricValue();
335 template <
typename Po
intType>
353 template <
typename Po
intType>
354 std::pair<physics::MetricRange, physics::Distance>
calculateWidthRange(std::vector<PointType>
const &edgeLeft,
355 physics::Distance
const &edgeLeftLength,
356 std::vector<PointType>
const &edgeRight,
357 physics::Distance
const &edgeRightLength)
359 physics::MetricRange widthRange;
360 widthRange.minimum = std::numeric_limits<physics::Distance>::max();
361 widthRange.maximum = physics::Distance(0.);
362 physics::Distance widthSum(0.);
363 size_t widthSumCount(0u);
364 physics::ParametricValue parametricStepsize(0.5);
365 auto length = (edgeLeftLength + edgeRightLength) * 0.5;
366 if (length > physics::Distance(1.))
369 = std::max(physics::ParametricValue(0.01), physics::ParametricValue(1. /
static_cast<double>(length)));
371 physics::ParametricValue longitudinalOffset(0.);
372 bool endReached =
false;
379 return std::make_pair(physics::MetricRange(), physics::Distance());
384 return std::make_pair(physics::MetricRange(), physics::Distance());
388 if (!isRangeValid(longTLeft) || !isRangeValid(longTRight))
390 return std::make_pair(physics::MetricRange(), physics::Distance());
393 auto const pointOnRightEdge =
getParametricPoint(edgeRight, edgeRightLength, longTRight);
396 return std::make_pair(physics::MetricRange(), physics::Distance());
398 physics::Distance
const width =
distance(pointOnLeftEdge, pointOnRightEdge);
399 unionRangeWith(widthRange, width);
402 if (longitudinalOffset < physics::ParametricValue(1.))
404 longitudinalOffset += parametricStepsize;
405 if (longitudinalOffset > physics::ParametricValue(1.))
407 longitudinalOffset = physics::ParametricValue(1.);
414 }
while (!endReached);
416 auto averageWidth = (widthSum /
static_cast<double>(widthSumCount));
418 return std::make_pair(widthRange, averageWidth);
439 template <
typename Po
intType>
441 physics::Distance
const &leftEdgeLength,
442 std::vector<PointType>
const &rightEdge,
443 physics::Distance
const &rightEdgeLength,
444 physics::ParametricValue
const lateralAlignment)
446 typedef std::vector<PointType> EdgeType;
450 throw std::invalid_argument(
"ad::map::point::getLateralAlignmentEdge()"
451 " the given lateralAlignment is out of range");
454 EdgeType
const *primary;
455 EdgeType
const *secondary;
456 physics::Distance primaryLength;
457 physics::Distance secondaryLength;
458 physics::ParametricValue lateralOffset = lateralAlignment;
459 if (leftEdge.size() > rightEdge.size())
462 primaryLength = leftEdgeLength;
463 secondary = &rightEdge;
464 secondaryLength = rightEdgeLength;
465 lateralOffset = physics::ParametricValue(1.) - lateralAlignment;
469 primary = &rightEdge;
470 primaryLength = rightEdgeLength;
471 secondary = &leftEdge;
472 secondaryLength = leftEdgeLength;
476 EdgeType alignmentEdge;
477 alignmentEdge.reserve(primaryParametric.size());
478 for (
size_t i = 0; i < primaryParametric.size(); i++)
480 PointType
const &pri = primary->at(i);
481 PointType
const sec =
getParametricPoint(*secondary, secondaryLength, primaryParametric[i]);
483 alignmentEdge.push_back(alignmentPoint);
485 return alignmentEdge;
506 template <
typename Po
intType>
508 std::vector<PointType>
const &rightEdge,
509 physics::ParametricValue
const lateralAlignment)
524 if (edge.size() <= 1u)
529 auto edgeStartVec = edge[1u] - edge[0u];
533 edgeStartVec = edge[2u] - edge[0u];
547 if (edge.size() <= 1u)
552 auto edgeEndVec = edge[edge.size() - 1u] - edge[edge.size() - 2u];
556 edgeEndVec = edge[edge.size() - 1u] - edge[edge.size() - 3u];