Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
RingIntersection.hpp
Go to the documentation of this file.
1#pragma once
2#include <ranges>
4
5namespace fishnet::geometry {
6
27template<typename R, LinearGeometry L>
28constexpr static bool ringIntersects(const R & ring, const L & linearFeature) noexcept {
29 auto segments = ring.getSegments();
30 using difference_type = std::ranges::range_difference_t<decltype(segments)>;
31 auto size = std::ranges::ssize(segments);
32 auto segmentAt = [&segments](difference_type index){return *(std::ranges::begin(segments) + index);};
33 // Helper lambda to check whether two points are on the same side of the linearFeature (or on the line)
34 auto onSameSide = [&linearFeature](const auto & lhs, const auto & rhs) {
35 auto line = linearFeature.toLine();
36 if(line.contains(rhs) || line.contains(lhs)){
37 return true;
38 }
39 return line.isLeft(lhs) == line.isLeft(rhs);
40 };
41 for(difference_type i = 0; i < size; ++i){
42 auto current = segmentAt(i);
43 auto inter = current.intersection(linearFeature);
44 if constexpr(ISegment<L>){
45 if(inter && (linearFeature.isEndpoint(inter.value()) && current.isEndpoint(inter.value())))
46 continue;
47 if(inter && (linearFeature.isEndpoint(inter.value())) && (ring.isOutside(linearFeature.p()) || ring.isOutside(linearFeature.q())))
48 return true;
49 }
50 if constexpr(IRay<L>){
51 if(inter && inter.value() == linearFeature.origin())
52 continue;
53 }
54 if(inter && current.isEndpoint(inter.value())) { // intersection is vertex of ring
55 if(current.p() == inter.value()){
56 // i+size-1 rather than i-1: the latter underflows for i == 0 and then only wraps
57 // to size-1 when the number of segments happens to be a power of two
58 if(not onSameSide(current.q(),segmentAt((i+size-1)%size).p()))
59 return true;
60 }else{ // inter.value() == current.q()
61 if(not onSameSide(current.p(),segmentAt((i+1)%size).q()))
62 return true;
63 }
64 }else if(inter){
65 if(not onSameSide(current.p(),current.q())) return true;
66 }
67 }
68 return false;
69}
70} // namespace fishnet::geometry
Interface for a ray A ray is defined through its origin and a direction.
Definition IRay.hpp:69
Interface for a segment A segment is formed between two points p and q, containing only the points on...
Definition ISegment.hpp:105
Definition BoundingBoxWrapper.hpp:5
static constexpr bool ringIntersects(const R &ring, const L &linearFeature) noexcept
test whether a linear feature intersects a ring Check every intersection of the linear feature with t...
Definition RingIntersection.hpp:28