Skip to content

Commit

Permalink
fix: Fix CircleShape.computeDistanceToOut and add some tests. (#100)
Browse files Browse the repository at this point in the history
# Description

<!-- Provide a description of what this PR is doing. 
If you're modifying existing behavior, describe the existing behavior,
how this PR is changing it,
and what motivated the change. If this is a breaking change, specify
explicitly which APIs have been
changed. -->

## Checklist

<!-- Before you create this PR confirm that it meets all requirements
listed below by checking the
relevant checkboxes (`[x]`). This will ensure a smooth and quick review
process. -->

- [x] The title of my PR starts with a [Conventional Commit] prefix
(`fix:`, `feat:`, `docs:` etc).
- [x] I have read the [Contributor Guide] and followed the process
outlined for submitting PRs.
- [x] I have updated/added tests for ALL new/updated/fixed
functionality.
- [ ] (N/A) I have updated/added relevant documentation in `docs` and
added dartdoc comments with `///`.
- [ ] (N/A) I have updated/added relevant examples in `examples`.

## Breaking Change

<!-- Does your PR require Flame users to manually update their apps to
accommodate your change?

If the PR is a breaking change this should be indicated with suffix "!"
(for example, `feat!:`, `fix!:`). See [Conventional Commit] for details.
-->

- [ ] Yes, this is a breaking change.
- [x] No, this is *not* a breaking change.

## Related Issues

<!-- Provide a list of issues related to this PR from the [issue
database].
Indicate which of these issues are resolved or fixed by this PR, i.e.
Fixes #xxxx* !-->
Fixes #99.

<!-- Links -->
[issue database]: https://github.com/flame-engine/flame/issues
[Contributor Guide]:
https://github.com/flame-engine/flame/blob/main/CONTRIBUTING.md
[Flame Style Guide]:
https://github.com/flame-engine/flame/blob/main/STYLEGUIDE.md
[Conventional Commit]: https://conventionalcommits.org

Co-authored-by: drrnbrns <dburns@example.com>
  • Loading branch information
drrnbrns and drrnbrns authored Dec 18, 2024
1 parent 9386343 commit 584a07e
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 5 deletions.
9 changes: 4 additions & 5 deletions packages/forge2d/lib/src/collision/shapes/circle_shape.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,10 @@ class CircleShape extends Shape {
int childIndex,
Vector2 normalOut,
) {
final xfq = xf.q;
final centerX = xfq.cos * p.x - xfq.sin * p.y + xf.p.x;
final centerY = xfq.sin * p.x + xfq.cos * p.y + xf.p.y;
final dx = p.x - centerX;
final dy = p.y - centerY;
final q = xf.q;
final tp = xf.p;
final dx = -(q.cos * position.x - q.sin * position.y + tp.x - p.x);
final dy = -(q.sin * position.x + q.cos * position.y + tp.y - p.y);
final d1 = sqrt(dx * dx + dy * dy);
normalOut.x = dx * 1 / d1;
normalOut.y = dy * 1 / d1;
Expand Down
27 changes: 27 additions & 0 deletions packages/forge2d/test/collision/shapes/circle_shape_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,32 @@ void main() {
expect(clonedCircleShape.radius, equals(radius));
expect(clonedCircleShape.position, equals(position));
});

test('Test computeDistanceToOut', () {
void checkDistance(
Transform tf,
Vector2 testPoint,
double expectedDistance,
Vector2 expectedNormal,
) {
const radius = 3.0;
final position = Vector2(1.0, 2.0);
final circleShape = CircleShape(radius: radius, position: position);
final normal = Vector2.zero();
final distance =
circleShape.computeDistanceToOut(tf, testPoint, 0, normal);
expect(distance, closeTo(expectedDistance, 0.01));
expect(normal.x, closeTo(expectedNormal.x, 0.01));
expect(normal.y, closeTo(expectedNormal.y, 0.01));
}

final tfZero = Transform.zero();
checkDistance(tfZero, Vector2(10, 7), 7.3, Vector2(0.87, 0.49));
checkDistance(tfZero, Vector2(1, -5), 4.0, Vector2(0.0, -1.0));

final tf2 = Transform.zero()..setVec2Angle(Vector2(10, 10), 0.2);
checkDistance(tf2, Vector2(10, 7), 7.59, Vector2(0.89, 0.46));
checkDistance(tf2, Vector2(1, -5), 4.17, Vector2(0.06, -1.0));
});
});
}
61 changes: 61 additions & 0 deletions packages/forge2d/test/collision/shapes/polygon_shape_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'package:forge2d/forge2d.dart';
import 'package:test/test.dart';

void main() {
group('PolygonShape', () {
test('Test setAsBoxXY', () {
final polygonShape = PolygonShape()..setAsBoxXY(3, 4);
expect(
polygonShape.vertices,
equals([
Vector2(-3.0, -4.0),
Vector2(3.0, -4.0),
Vector2(3.0, 4.0),
Vector2(-3.0, 4.0),
]),
);
expect(
polygonShape.normals,
equals([
Vector2(0.0, -1.0),
Vector2(1.0, 0.0),
Vector2(0.0, 1.0),
Vector2(-1.0, 0.0),
]),
);
});

test('Test clone', () {
final polygonShape = PolygonShape()..setAsBoxXY(3, 4);
final clonedPolygonShape = polygonShape.clone() as PolygonShape;
expect(clonedPolygonShape.radius, equals(polygonShape.radius));
expect(clonedPolygonShape.vertices, equals(polygonShape.vertices));
expect(clonedPolygonShape.normals, equals(polygonShape.normals));
});

test('Test computeDistanceToOut', () {
void checkDistance(
Transform tf,
Vector2 testPoint,
double expectedDistance,
Vector2 expectedNormal,
) {
final polygonShape = PolygonShape()..setAsBoxXY(3, 4);
final normal = Vector2.zero();
final distance =
polygonShape.computeDistanceToOut(tf, testPoint, 0, normal);
expect(distance, closeTo(expectedDistance, 0.01));
expect(normal.x, closeTo(expectedNormal.x, 0.01));
expect(normal.y, closeTo(expectedNormal.y, 0.01));
}

final tfZero = Transform.zero();
checkDistance(tfZero, Vector2(10, 7), 7.0, Vector2(1.0, 0.0));
checkDistance(tfZero, Vector2(1, -5), 1.0, Vector2(0.0, -1.0));

final tf2 = Transform.zero()..setVec2Angle(Vector2(10, 10), 0.2);
checkDistance(tf2, Vector2(10, 7), 8.2, Vector2(0.98, 0.2));
checkDistance(tf2, Vector2(1, -5), 1.1, Vector2(0.2, -0.98));
});
});
}

0 comments on commit 584a07e

Please sign in to comment.