| 2518 | } |
| 2519 | |
| 2520 | double PathObject::calcMaximumDistanceTo( |
| 2521 | MapCoordVector::size_type start_index, |
| 2522 | MapCoordVector::size_type end_index, |
| 2523 | const PathObject* other, |
| 2524 | MapCoordVector::size_type other_start_index, |
| 2525 | MapCoordVector::size_type other_end_index) const |
| 2526 | { |
| 2527 | update(); |
| 2528 | |
| 2529 | Q_ASSERT(other_start_index == 0); |
| 2530 | Q_ASSERT(other_end_index == other->coords.size()-1); |
| 2531 | |
| 2532 | if (end_index < start_index) |
| 2533 | { |
| 2534 | const auto part = findPartForIndex(start_index); |
| 2535 | Q_ASSERT(part->isClosed()); |
| 2536 | Q_ASSERT(end_index >= part->first_index); |
| 2537 | Q_ASSERT(end_index <= part->last_index); |
| 2538 | auto d1 = calcMaximumDistanceTo(start_index, part->last_index, other, other_start_index, other_end_index); |
| 2539 | auto d2 = calcMaximumDistanceTo(part->first_index, end_index, other, other_start_index, other_end_index); |
| 2540 | return qMax(d1, d2); |
| 2541 | } |
| 2542 | |
| 2543 | const auto test_points_per_mm = 2.0; |
| 2544 | |
| 2545 | auto max_distance_sq = 0.0; |
| 2546 | for (const auto& part : path_parts) |
| 2547 | { |
| 2548 | if (part.first_index <= end_index && part.last_index >= start_index ) |
| 2549 | { |
| 2550 | const auto& path_coords = part.path_coords; |
| 2551 | |
| 2552 | auto pc_start = std::lower_bound(begin(path_coords), end(path_coords), start_index, PathCoord::indexLessThanValue); |
| 2553 | auto pc_end = std::lower_bound(pc_start, end(path_coords), end_index, PathCoord::indexLessThanValue); |
| 2554 | if (pc_end == end(path_coords)) |
| 2555 | { |
| 2556 | if (pc_end != pc_start) |
| 2557 | --pc_end; |
| 2558 | } |
| 2559 | |
| 2560 | auto closest = other->findClosestPointTo(pc_start->pos, other_start_index, other_end_index); |
| 2561 | max_distance_sq = qMax(max_distance_sq, closest.distance_squared); |
| 2562 | |
| 2563 | for (auto pc = pc_start; pc != pc_end; ++pc) |
| 2564 | { |
| 2565 | auto next_pc = pc + 1; |
| 2566 | auto len = double(next_pc->clen) - double(pc->clen); |
| 2567 | MapCoordF direction = next_pc->pos - pc->pos; |
| 2568 | |
| 2569 | int num_test_points = qMax(1, qRound(len * test_points_per_mm)); |
| 2570 | for (int p = 1; p <= num_test_points; ++p) |
| 2571 | { |
| 2572 | MapCoordF point = pc->pos + direction * (double(p) / num_test_points); |
| 2573 | closest = other->findClosestPointTo(point, other_start_index, other_end_index); |
| 2574 | max_distance_sq = qMax(max_distance_sq, closest.distance_squared); |
| 2575 | } |
| 2576 | } |
| 2577 | } |
no test coverage detected