Skip to content
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: Vertices in PolygonComponent should subtract vertices positioning #3040

Merged
merged 3 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions packages/flame/lib/src/geometry/polygon_component.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ class PolygonComponent extends ShapeComponent {
/// With this constructor you create your [PolygonComponent] from positions in
/// anywhere in the 2d-space. It will automatically calculate the [size] of
/// the Polygon (the bounding box) if no size it given.
/// NOTE: Always define your polygon in a counter-clockwise fashion (in the
/// screen coordinate system).
PolygonComponent(
this._vertices, {
super.position,
Expand Down Expand Up @@ -110,10 +108,6 @@ class PolygonComponent extends ShapeComponent {
.toList(growable: false);
}

// Used to not create new Vector2 objects when calculating the top left of the
// bounds of the polygon.
final _topLeft = Vector2.zero();

@protected
void refreshVertices({
required List<Vector2> newVertices,
Expand All @@ -128,24 +122,29 @@ class PolygonComponent extends ShapeComponent {
if (_isClockwise(newVertices)) {
newVertices.reverse();
}
_topLeft.setFrom(newVertices[0]);
newVertices.forEachIndexed((i, _) {
final topLeft = Vector2.zero();
topLeft.setFrom(newVertices[0]);
for (var i = 0; i < newVertices.length; i++) {
final newVertex = newVertices[i];
_vertices[i].setFrom(newVertex);
_topLeft.x = min(_topLeft.x, newVertex.x);
_topLeft.y = min(_topLeft.y, newVertex.y);
});
topLeft.x = min(topLeft.x, newVertex.x);
topLeft.y = min(topLeft.y, newVertex.y);
}
for (var i = 0; i < newVertices.length; i++) {
final newVertex = newVertices[i];
_vertices[i].setFrom(newVertex - topLeft);
}
_path
..reset()
..addPolygon(
vertices.map((p) => (p - _topLeft).toOffset()).toList(growable: false),
_vertices.map((p) => p.toOffset()).toList(growable: false),
true,
);
if (shrinkToBoundsOverride ?? shrinkToBounds) {
final bounds = _path.getBounds();
size.setValues(bounds.width, bounds.height);
if (!manuallyPositioned) {
position = Anchor.topLeft.toOtherAnchorPosition(_topLeft, anchor, size);
position = Anchor.topLeft.toOtherAnchorPosition(topLeft, anchor, size);
}
}
}
Expand All @@ -161,14 +160,14 @@ class PolygonComponent extends ShapeComponent {
scale,
angle,
])) {
vertices.forEachIndexed((i, vertex) {
for (var i = 0; i < _vertices.length; i++) {
final vertex = _vertices[i];
_globalVertices[i]
..setFrom(vertex)
..sub(_topLeft)
..multiply(scale)
..add(position)
..rotate(angle, center: position);
});
}
if (scale.y.isNegative || scale.x.isNegative) {
// Since the list will be clockwise we have to reverse it for it to
// become counterclockwise.
Expand Down Expand Up @@ -255,11 +254,7 @@ class PolygonComponent extends ShapeComponent {

@override
bool containsLocalPoint(Vector2 point) {
// Take anchor into consideration.
final localPoint =
anchor.toOtherAnchorPosition(point, Anchor.topLeft, size);

return _containsPoint(localPoint, _vertices);
return _containsPoint(point, _vertices);
}

/// Return all vertices as [LineSegment]s that intersect [rect], if [rect]
Expand Down
28 changes: 27 additions & 1 deletion packages/flame/test/components/shape_component_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,34 @@ void main() {
Vector2(1.5, 0.5),
],
);
expect(polygon.containsLocalPoint(Vector2(0.25, 0.25)), isFalse);
expect(polygon.containsLocalPoint(Vector2(0.0, 0.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.25, 0.25)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.75, 0.75)), isTrue);
expect(polygon.containsLocalPoint(Vector2(1.0, 1.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(1.0, 0.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.0, 1.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.0, 1.0001)), isFalse);
expect(polygon.containsLocalPoint(Vector2(-0.0001, 0.0)), isFalse);
});

test('polygon contains point in local with anchor', () {
final polygon = PolygonComponent(
[
Vector2(0.5, 0.5),
Vector2(0.5, 1.5),
Vector2(1.5, 1.5),
Vector2(1.5, 0.5),
],
anchor: Anchor.center,
);
expect(polygon.containsLocalPoint(Vector2(0.0, 0.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.25, 0.25)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.75, 0.75)), isTrue);
expect(polygon.containsLocalPoint(Vector2(1.0, 1.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(1.0, 0.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.0, 1.0)), isTrue);
expect(polygon.containsLocalPoint(Vector2(0.0, 1.0001)), isFalse);
expect(polygon.containsLocalPoint(Vector2(-0.0001, 0.0)), isFalse);
});

test('rectangle contains point in local with anchor', () {
Expand Down
Loading