diff --git a/packages/forge2d/lib/src/collision/shapes/circle_shape.dart b/packages/forge2d/lib/src/collision/shapes/circle_shape.dart index 2de57d8..b872556 100644 --- a/packages/forge2d/lib/src/collision/shapes/circle_shape.dart +++ b/packages/forge2d/lib/src/collision/shapes/circle_shape.dart @@ -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; diff --git a/packages/forge2d/test/collision/shapes/circle_shape_test.dart b/packages/forge2d/test/collision/shapes/circle_shape_test.dart index 449ca9f..ecd1265 100644 --- a/packages/forge2d/test/collision/shapes/circle_shape_test.dart +++ b/packages/forge2d/test/collision/shapes/circle_shape_test.dart @@ -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)); + }); }); } diff --git a/packages/forge2d/test/collision/shapes/polygon_shape_test.dart b/packages/forge2d/test/collision/shapes/polygon_shape_test.dart new file mode 100644 index 0000000..6c2e549 --- /dev/null +++ b/packages/forge2d/test/collision/shapes/polygon_shape_test.dart @@ -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)); + }); + }); +}