@@ -492,6 +492,7 @@ passes through an odd number of edges, it is within the curve, else outside of
492492of the curve if it didn't return 'on'.
493493See paper for more information on cases denoted in comments.
494494=#
495+
495496function _point_filled_curve_orientation (
496497 :: Planar , point, curve;
497498 in:: T = point_in, on:: T = point_on, out:: T = point_out, exact,
@@ -527,6 +528,54 @@ function _point_filled_curve_orientation(
527528 end
528529 return iseven (k) ? out : in
529530end
531+
532+ # Specialized implementation for NaturallyIndexedRing
533+ # This relies on multidispatch.
534+ # TODO : remove?
535+ function _point_filled_curve_orientation (
536+ :: Planar , point, curve:: NaturalIndexing.NaturallyIndexedRing ;
537+ in:: T = point_in, on:: T = point_on, out:: T = point_out, exact,
538+ ) where {T}
539+ x, y = GI. x (GI. PointTrait (), point), GI. y (GI. PointTrait (), point)
540+ k:: Int = 0 # counter for ray crossings
541+
542+ tree = curve. index
543+
544+ function per_edge_function (i)
545+ p_start = _tuple_point (GI. getpoint (curve, i))
546+ p_end = _tuple_point (GI. getpoint (curve, i + 1 ))
547+ v1 = GI. y (p_start) - y
548+ v2 = GI. y (p_end) - y
549+ if ! ((v1 < 0 && v2 < 0 ) || (v1 > 0 && v2 > 0 )) # if not cases 11 or 26
550+ u1, u2 = GI. x (p_start) - x, GI. x (p_end) - x
551+ f = Predicates. orient (p_start, p_end, (x, y); exact)
552+ if v2 > 0 && v1 ≤ 0 # Case 3, 9, 16, 21, 13, or 24
553+ f == 0 && return LSM. Action {T} (:full_return , on) # Case 16 or 21
554+ f > 0 && (k += 1 ) # Case 3 or 9
555+ elseif v1 > 0 && v2 ≤ 0 # Case 4, 10, 19, 20, 12, or 25
556+ f == 0 && return LSM. Action {T} (:full_return , on) # Case 19 or 20
557+ f < 0 && (k += 1 ) # Case 4 or 10
558+ elseif v2 == 0 && v1 < 0 # Case 7, 14, or 17
559+ f == 0 && return LSM. Action {T} (:full_return , on) # Case 17
560+ elseif v1 == 0 && v2 < 0 # Case 8, 15, or 18
561+ f == 0 && return LSM. Action {T} (:full_return , on) # Case 18
562+ elseif v1 == 0 && v2 == 0 # Case 1, 2, 5, 6, 22, or 23
563+ u2 ≤ 0 && u1 ≥ 0 && return LSM. Action {T} (:full_return , on) # Case 1
564+ u1 ≤ 0 && u2 ≥ 0 && return LSM. Action {T} (:full_return , on) # Case 2
565+ end
566+ return LSM. Action (:continue , on)
567+ end
568+ p_start = p_end
569+ end
570+
571+ result = SpatialTreeInterface. depth_first_search (per_edge_function,extent -> extent. Y[1 ] <= y <= extent. Y[2 ], tree)
572+
573+ if result isa LoopStateMachine. Action
574+ return result. x
575+ else
576+ return iseven (k) ? out : in
577+ end
578+ end
530579_point_filled_curve_orientation (
531580 point, curve;
532581 in:: T = point_in, on:: T = point_on, out:: T = point_out, exact,
0 commit comments