Skip to content

Commit 5e1b1a8

Browse files
author
drrnbrns
committed
Fix CircleShape.computeDistanceToOut and add some tests.
1 parent 9386343 commit 5e1b1a8

File tree

3 files changed

+92
-5
lines changed

3 files changed

+92
-5
lines changed

packages/forge2d/lib/src/collision/shapes/circle_shape.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ class CircleShape extends Shape {
5555
int childIndex,
5656
Vector2 normalOut,
5757
) {
58-
final xfq = xf.q;
59-
final centerX = xfq.cos * p.x - xfq.sin * p.y + xf.p.x;
60-
final centerY = xfq.sin * p.x + xfq.cos * p.y + xf.p.y;
61-
final dx = p.x - centerX;
62-
final dy = p.y - centerY;
58+
final q = xf.q;
59+
final tp = xf.p;
60+
final dx = -(q.cos * position.x - q.sin * position.y + tp.x - p.x);
61+
final dy = -(q.sin * position.x + q.cos * position.y + tp.y - p.y);
6362
final d1 = sqrt(dx * dx + dy * dy);
6463
normalOut.x = dx * 1 / d1;
6564
normalOut.y = dy * 1 / d1;

packages/forge2d/test/collision/shapes/circle_shape_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,32 @@ void main() {
2323
expect(clonedCircleShape.radius, equals(radius));
2424
expect(clonedCircleShape.position, equals(position));
2525
});
26+
27+
test('Test computeDistanceToOut', () {
28+
void checkDistance(
29+
Transform tf,
30+
Vector2 testPoint,
31+
double expectedDistance,
32+
Vector2 expectedNormal,
33+
) {
34+
const radius = 3.0;
35+
final position = Vector2(1.0, 2.0);
36+
final circleShape = CircleShape(radius: radius, position: position);
37+
final normal = Vector2.zero();
38+
final distance =
39+
circleShape.computeDistanceToOut(tf, testPoint, 0, normal);
40+
expect(distance, closeTo(expectedDistance, 0.01));
41+
expect(normal.x, closeTo(expectedNormal.x, 0.01));
42+
expect(normal.y, closeTo(expectedNormal.y, 0.01));
43+
}
44+
45+
final tfZero = Transform.zero();
46+
checkDistance(tfZero, Vector2(10, 7), 7.3, Vector2(0.87, 0.49));
47+
checkDistance(tfZero, Vector2(1, -5), 4.0, Vector2(0.0, -1.0));
48+
49+
final tf2 = Transform.zero()..setVec2Angle(Vector2(10, 10), 0.2);
50+
checkDistance(tf2, Vector2(10, 7), 7.59, Vector2(0.89, 0.46));
51+
checkDistance(tf2, Vector2(1, -5), 4.17, Vector2(0.06, -1.0));
52+
});
2653
});
2754
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import 'package:forge2d/forge2d.dart';
2+
import 'package:test/test.dart';
3+
4+
void main() {
5+
group('PolygonShape', () {
6+
test('Test setAsBoxXY', () {
7+
final polygonShape = PolygonShape()..setAsBoxXY(3, 4);
8+
expect(
9+
polygonShape.vertices,
10+
equals([
11+
Vector2(-3.0, -4.0),
12+
Vector2(3.0, -4.0),
13+
Vector2(3.0, 4.0),
14+
Vector2(-3.0, 4.0),
15+
]),
16+
);
17+
expect(
18+
polygonShape.normals,
19+
equals([
20+
Vector2(0.0, -1.0),
21+
Vector2(1.0, 0.0),
22+
Vector2(0.0, 1.0),
23+
Vector2(-1.0, 0.0),
24+
]),
25+
);
26+
});
27+
28+
test('Test clone', () {
29+
final polygonShape = PolygonShape()..setAsBoxXY(3, 4);
30+
final clonedPolygonShape = polygonShape.clone() as PolygonShape;
31+
expect(clonedPolygonShape.radius, equals(polygonShape.radius));
32+
expect(clonedPolygonShape.vertices, equals(polygonShape.vertices));
33+
expect(clonedPolygonShape.normals, equals(polygonShape.normals));
34+
});
35+
36+
test('Test computeDistanceToOut', () {
37+
void checkDistance(
38+
Transform tf,
39+
Vector2 testPoint,
40+
double expectedDistance,
41+
Vector2 expectedNormal,
42+
) {
43+
final polygonShape = PolygonShape()..setAsBoxXY(3, 4);
44+
final normal = Vector2.zero();
45+
final distance =
46+
polygonShape.computeDistanceToOut(tf, testPoint, 0, normal);
47+
expect(distance, closeTo(expectedDistance, 0.01));
48+
expect(normal.x, closeTo(expectedNormal.x, 0.01));
49+
expect(normal.y, closeTo(expectedNormal.y, 0.01));
50+
}
51+
52+
final tfZero = Transform.zero();
53+
checkDistance(tfZero, Vector2(10, 7), 7.0, Vector2(1.0, 0.0));
54+
checkDistance(tfZero, Vector2(1, -5), 1.0, Vector2(0.0, -1.0));
55+
56+
final tf2 = Transform.zero()..setVec2Angle(Vector2(10, 10), 0.2);
57+
checkDistance(tf2, Vector2(10, 7), 8.2, Vector2(0.98, 0.2));
58+
checkDistance(tf2, Vector2(1, -5), 1.1, Vector2(0.2, -0.98));
59+
});
60+
});
61+
}

0 commit comments

Comments
 (0)