Closed zer0ner closed 1 year ago
I ended up writing my own 4RPL implementation based on a function from StackOverflow for map 1161 (The Aquarium):
# IsPointInPoly(point polyList)
:IsPointInPoly
->ipip_polyList
->ipip_point
false ->ipip_retval
GetListCount(<-ipip_polyList) 1 - ->ipip_prev
<-ipip_polyList 0 do
<-ipip_polyList[I] ->ipip_linept1
<-ipip_polyList[<-ipip_prev] ->ipip_linept2
if (<-ipip_linept1.y <-ipip_point.y gt <-ipip_linept2.y <-ipip_point.y gt neq)
<-ipip_linept2.x <-ipip_linept1.x - <-ipip_point.y <-ipip_linept1.y - * ->ipip_tempval
<-ipip_tempval <-ipip_linept2.y <-ipip_linept1.y - / ->ipip_tempval
<-ipip_tempval <-ipip_linept1.x + ->ipip_tempval
if (<-ipip_point.x <-ipip_tempval lt)
<-ipip_retval ! ->ipip_retval
endif
endif
I ->ipip_prev
loop
<-ipip_retval
This isn't the best nor most performant point in polygon function but it is able to be understood fairly easily. It doesn't work correctly if the polygon has holes and there are a few (literal) edge cases where it will fail as well. But it does work well enough for most concave/convex polygons, which is all I needed for my map.
You can contribute 4RPL code snippets to the wiki where it might be picked up by other 4RPL coders.
I already pointed you to this page and suggested you could start a new section there:
Is your feature request related to a problem? Please describe. Related to #822, determining if a specific X/Z cell position or a generic point is in a polygon does not have a simple 4RPL function available.
Describe the solution you'd like An easy way to pass in a specific X/Z cell position (or a V2()) and a list of X/Z cell positions representing a polygon and get back a boolean value if the specified position is inside the polygon.
Although the inputs will probably be map-related, the input coordinates don't need to be related to the actual map.
Describe alternatives you've considered A pure 4RPL script-level implementation is possible. Just not as convenient/performant as a globally-available function would be.