-
-
Notifications
You must be signed in to change notification settings - Fork 934
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
fix: Updated PolygonComponent.containsPoint to account for concave polygons #2979
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good after a quick look, how's the performance impact?
Just stress-tested the performance within my current project. So it takes about 43% longer on average. However, by replacing final edge = getEdge(i, vertices: vertices); with final from = vertices[i];
final to = vertices[(i + 1) % vertices.length]; It goes down to ~350ms and still survives every test. It's important to note that in my test, the old function returns false almost all the time. And looking at the code, returning false can happen much faster than checking all edges before returning true. |
@davidjan3 can you try with a bit more vertices, like 10? |
All polygons had 10-24 vertices. My test just ran the |
@spydon Code sample (useless of course, just to serve performance testing): final stopwatch = Stopwatch()..start();
for (Vector2 vertex in rect.globalVertices()) {
for (PolygonComponent polygon in polygons) {
// polygon is a random convex or concave polygon with between 10 and 24 vertices
collided = polygon.containsPoint(vertex);
}
}
log("Collision check took ${stopwatch.elapsedMilliseconds} ms"); Ran this in a loop and it kept averaging around the numbers stated in earlier comments. If you like, I can push the version where |
Sounds good, seems like a reasonable performance trade-off. |
@spydon So would you prefer keeping the
That way its worst case would outperform the old implementation's average, so no performance trade-off :) |
@davidjan3 sounds like it's definitely worth changing it then! :) |
@spydon Added said optimization, and a little test :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm! Sorry for the delay, I've been away skiing in the alps the last week 😅
Description
Previously, the
PolygonComponent.containsPoint()
and.containsLocalPoint()
functions consisted of duplicate code that checked whether a given point lies within a convex polygon. They didn't function properly with concave polygons.I created a new
_containsPoint()
function that is called from both functions to reduce redundancies. This new function uses a different approach to figure out whether a point lies within a polygon, which should also work for concave polygons, or even polygons with holes. The algorithm is vaguely explained within code comments, and is visualized in this post: https://stackoverflow.com/a/218081/5008997Checklist
docs
and added dartdoc comments with///
.examples
ordocs
.Breaking Change?
Related Issues