| 2598 | } |
| 2599 | |
| 2600 | void PathObject::calcAllIntersectionsWith(const PathObject* other, PathObject::Intersections& out) const |
| 2601 | { |
| 2602 | update(); |
| 2603 | other->update(); |
| 2604 | |
| 2605 | const double epsilon = 1e-10; |
| 2606 | const double zero_minus_epsilon = 0 - epsilon; |
| 2607 | const double one_plus_epsilon = 1 + epsilon; |
| 2608 | |
| 2609 | for (size_t part_index = 0; part_index < path_parts.size(); ++part_index) |
| 2610 | { |
| 2611 | const PathPart& part = path_parts[part_index]; |
| 2612 | auto path_coord_end_index = part.path_coords.size() - 1; |
| 2613 | for (auto i = PathCoordVector::size_type { 1 }; i <= path_coord_end_index; ++i) |
| 2614 | { |
| 2615 | // Get information about this path coord |
| 2616 | bool has_segment_before = (i > 1) || part.isClosed(); |
| 2617 | MapCoordF ingoing_direction; |
| 2618 | if (has_segment_before && i == 1) |
| 2619 | { |
| 2620 | Q_ASSERT(path_coord_end_index >= 1); |
| 2621 | ingoing_direction = part.path_coords[path_coord_end_index].pos - part.path_coords[path_coord_end_index - 1].pos; |
| 2622 | ingoing_direction.normalize(); |
| 2623 | } |
| 2624 | else if (has_segment_before) |
| 2625 | { |
| 2626 | Q_ASSERT(i >= 1 && i < part.path_coords.size()); |
| 2627 | ingoing_direction = part.path_coords[i-1].pos - part.path_coords[i-2].pos; |
| 2628 | ingoing_direction.normalize(); |
| 2629 | } |
| 2630 | |
| 2631 | bool has_segment_after = (i < path_coord_end_index) || part.isClosed(); |
| 2632 | MapCoordF outgoing_direction; |
| 2633 | if (has_segment_after && i == path_coord_end_index) |
| 2634 | { |
| 2635 | Q_ASSERT(part.path_coords.size() > 1); |
| 2636 | outgoing_direction = part.path_coords[1].pos - part.path_coords[0].pos; |
| 2637 | outgoing_direction.normalize(); |
| 2638 | } |
| 2639 | else if (has_segment_after) |
| 2640 | { |
| 2641 | Q_ASSERT(i < path_coord_end_index); |
| 2642 | outgoing_direction = part.path_coords[i+1].pos - part.path_coords[i].pos; |
| 2643 | outgoing_direction.normalize(); |
| 2644 | } |
| 2645 | |
| 2646 | // Collision state with other object at current other path coord |
| 2647 | bool colliding = false; |
| 2648 | // Last known intersecting point. |
| 2649 | // This is valid as long as colliding == true and entered as intersection |
| 2650 | // when the next segment suddenly is not colliding anymore. |
| 2651 | Intersection last_intersection; |
| 2652 | |
| 2653 | for (size_t other_part_index = 0; other_part_index < other->path_parts.size(); ++other_part_index) |
| 2654 | { |
| 2655 | const PathPart& other_part = other->path_parts[part_index]; /// \todo FIXME: part_index or other_part_index ??? |
| 2656 | auto other_path_coord_end_index = other_part.path_coords.size() - 1; |
| 2657 | for (auto k = PathCoordVector::size_type { 1 }; k <= other_path_coord_end_index; ++k) |
no test coverage detected