New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Geometry.is_point_in_polygon() fails when points are clockwise #69505
Comments
This was solved on reddit. A careful look at the coordinates reveals that this is an anticlockwise polygon. It thus considers the point, which is on the exact edge (adding to the confusion), to be outside the inverted polygon. |
Thanks. IMHO, the documentation should be updated though; AFAICS it makes no mention of clockwise or anticlockwise or that they are even a thing to know about. |
For reference: reddit thread. @TheDuriel It's not solved. Even if it's intended to consider the edges to be a part of / not be a part of the polygon based on the winding order then it still seems to be bugged for the corners/vertices: Test script:tool
extends EditorScript
func _run() -> void:
var results_format_string := " %10s: %5s %5s"
for rect in [
Rect2(0, 0, 5, 5),
Rect2(0, 0, 10, 20),
Rect2(0, 0, 7, 13),
Rect2(0, 0, 111, 11),
Rect2(0, 0, 45, 3),
Rect2(231, 351, 5, 87),
Rect2(0, 0, 100, 20),
]:
print()
print("Rect: %s" % [rect])
var polygon := PoolVector2Array([
rect.position,
rect.position + rect.size * Vector2(1, 0),
rect.position + rect.size * Vector2(1, 1),
rect.position + rect.size * Vector2(0, 1),
])
var polygon_inv = polygon
polygon_inv.invert()
# print(" Inside points:")
for y in range(rect.position.y + 1, rect.end.y):
for x in range(rect.position.x + 1, rect.end.x):
var point := Vector2(x, y)
var r1 = Geometry.is_point_in_polygon(point, polygon)
var r2 = Geometry.is_point_in_polygon(point, polygon_inv)
if !r1 or !r2: # Assumption: these should always be considered inside.
print(results_format_string % [point, r1, r2])
# print(" Edge points:")
for y in range(rect.position.y + 1, rect.end.y):
for x in [rect.position.x, rect.end.x]:
var point := Vector2(x, y)
var r1 = Geometry.is_point_in_polygon(point, polygon)
var r2 = Geometry.is_point_in_polygon(point, polygon_inv)
if r1 == r2: # Assumption: these should differ based on the winding order.
print(results_format_string % [point, r1, r2])
for y in [rect.position.y, rect.end.y]:
for x in range(rect.position.x + 1, rect.end.x):
var point := Vector2(x, y)
var r1 = Geometry.is_point_in_polygon(point, polygon)
var r2 = Geometry.is_point_in_polygon(point, polygon_inv)
if r1 == r2: # Assumption: these should differ based on the winding order.
print(results_format_string % [point, r1, r2])
print(" Corner points:")
for point in polygon:
var r1 = Geometry.is_point_in_polygon(point, polygon)
var r2 = Geometry.is_point_in_polygon(point, polygon_inv)
# if r1 == r2: # Assumption: these should differ based on the winding order.
# But let's print all of them for showcase:
print(results_format_string % [point, r1, r2]) Results (v3.5.1.stable.official [6fed1ff]):
Hence it's not just a matter of documenting it. It's a |
Godot version
3.5.1
System information
Linux Mint
Issue description
Geometry.is_point_in_polygon() returns an incorrect result in the example below where the polygon points are clockwise, but works if I invert the points.
Steps to reproduce
I'm running the following code:-
As far as I can see, "result" should be true since (0, 1) is inside this polygon (which is just a rectangle) but it returns false.
If I add:-
It now returns true, which is correct.
Minimal reproduction project
n/a - See example code above
The text was updated successfully, but these errors were encountered: