mirror of
https://github.com/flame-engine/flame.git
synced 2025-11-14 03:40:21 +08:00
* Move out collision detection methods * Add possibility to define a hull for PositionComponents * Add example of how to use hull with tapable * Update contains point comment * Fix contains point * Hull should be based on center position * Remove collision detection parts * Use percentage of size instead of absolute size * Separate hull from PositionComponent * Clarify hull example * Fix formatting * Change to relative import * Use mixin for hitbox * Update changelog * Rename HasHitbox to Hitbox * Clarified names * Add spaces within braces * Removed extra spaces in the braces * Moved point rotation to Vector2 extension * Render hitbox within extension * Added collision detection * Add tests * Separate classes into files * Fix formatting * Move geometry files into geometry directory * Use relative import for mixin * Begin intersections between different shapes * Add shape class * Align with rebase * Fix CHANGELOG * Fix children positioning * New polygon intersection algorithm * No anchor for shape in PoC * Remove unused imports * Smarter bounding rectangle comparisons * Formatting * Add Circle to Circle collision * Circle-polygon intersections * Explanation of circle-circle intersections * Properly render circle circle collisions * Fix formatting * Better example * Update docs for collision detection * Fix formatting * Add polygon definition example * Update documentation about the shapes * Moved premature rc6 changelog line * Added a cache system for shape calculations * Fix formatting * Fix formatting * Fix imports * Add collidable polygon to example * Use anchorPosition for PositionComponent containsPoint * Fix angle problem for Rectangle * collisionCallback -> onCollision * Fixed Erick's comments * Improve collision detection example * Fix #662, zero size doesn't contain any points * Fix formatting * Can't contain point if x or y is 0 * Fix formatting * Fix test * Remove unnecessary collidable example part * Align with Draggable overhaul * Updated collision detection docs * Fix PR comments * Have more sensible Circle constructor * Clarify shape fields * Need ensureInitialized * Update docs to conform with switched constructors * Fix new definitions * Fix formatting * Update documentation * Fix formatting * Fix formatting * Exclude metrics check for test files * Add another simpler example of collision detection * Updated according to comments * Fix comments * Fix more comments * Fix more comments * Fix relative import * Fix comments * Moved export of geometry * Fix comments * Remove unused import * Fix assert for shape.component * Fix comments * Expect instead of assert in test
685 lines
20 KiB
Dart
685 lines
20 KiB
Dart
import 'package:flame/geometry.dart';
|
|
import 'package:flame/extensions.dart';
|
|
import 'package:flame/geometry.dart' as geometry;
|
|
import 'package:flame/src/geometry/circle.dart';
|
|
import 'package:flame/src/geometry/line_segment.dart';
|
|
import 'package:flame/src/geometry/line.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
void main() {
|
|
group('LineSegment.isPointOnSegment tests', () {
|
|
test('Can catch simple point', () {
|
|
final segment = LineSegment(
|
|
Vector2.all(0),
|
|
Vector2.all(1),
|
|
);
|
|
final point = Vector2.all(0.5);
|
|
expect(
|
|
segment.containsPoint(point),
|
|
true,
|
|
reason: 'Point should be on segment',
|
|
);
|
|
});
|
|
|
|
test('Should not catch point outside of segment, but on line', () {
|
|
final segment = LineSegment(
|
|
Vector2.all(0),
|
|
Vector2.all(1),
|
|
);
|
|
final point = Vector2.all(3);
|
|
expect(
|
|
segment.containsPoint(point),
|
|
false,
|
|
reason: 'Point should not be on segment',
|
|
);
|
|
});
|
|
|
|
test('Should not catch point outside of segment', () {
|
|
final segment = LineSegment(
|
|
Vector2.all(0),
|
|
Vector2.all(1),
|
|
);
|
|
final point = Vector2(3, 2);
|
|
expect(
|
|
segment.containsPoint(point),
|
|
false,
|
|
reason: 'Point should not be on segment',
|
|
);
|
|
});
|
|
|
|
test('Point on end of segment', () {
|
|
final segment = LineSegment(
|
|
Vector2.all(0),
|
|
Vector2.all(1),
|
|
);
|
|
final point = Vector2.all(1);
|
|
expect(
|
|
segment.containsPoint(point),
|
|
true,
|
|
reason: 'Point should be on segment',
|
|
);
|
|
});
|
|
|
|
test('Point on beginning of segment', () {
|
|
final segment = LineSegment(
|
|
Vector2.all(0),
|
|
Vector2.all(1),
|
|
);
|
|
final point = Vector2.all(0);
|
|
expect(
|
|
segment.containsPoint(point),
|
|
true,
|
|
reason: 'Point should be on segment',
|
|
);
|
|
});
|
|
});
|
|
|
|
group('LineSegment.intersections tests', () {
|
|
test('Simple intersection', () {
|
|
final segmentA = LineSegment(Vector2.all(0), Vector2.all(1));
|
|
final segmentB = LineSegment(Vector2(0, 1), Vector2(1, 0));
|
|
final intersection = segmentA.intersections(segmentB);
|
|
expect(
|
|
intersection.isNotEmpty,
|
|
true,
|
|
reason: 'Should have intersection at (0.5, 0.5)',
|
|
);
|
|
expect(intersection.first == Vector2.all(0.5), true);
|
|
});
|
|
|
|
test('No intersection', () {
|
|
final segmentA = LineSegment(Vector2.all(0), Vector2.all(1));
|
|
final segmentB = LineSegment(Vector2(0, 1), Vector2(1, 2));
|
|
final intersection = segmentA.intersections(segmentB);
|
|
expect(
|
|
intersection.isEmpty,
|
|
true,
|
|
reason: 'Should not have any intersection',
|
|
);
|
|
});
|
|
|
|
test('Same line segments', () {
|
|
final segmentA = LineSegment(Vector2.all(0), Vector2.all(1));
|
|
final segmentB = LineSegment(Vector2.all(0), Vector2.all(1));
|
|
final intersection = segmentA.intersections(segmentB);
|
|
expect(
|
|
intersection.isNotEmpty,
|
|
true,
|
|
reason: 'Should have intersection at (0.5, 0.5)',
|
|
);
|
|
expect(intersection.first == Vector2.all(0.5), true);
|
|
});
|
|
|
|
test('Overlapping line segments', () {
|
|
final segmentA = LineSegment(Vector2.all(0), Vector2.all(1));
|
|
final segmentB = LineSegment(Vector2.all(0.5), Vector2.all(1.5));
|
|
final intersection = segmentA.intersections(segmentB);
|
|
expect(
|
|
intersection.isNotEmpty,
|
|
true,
|
|
reason: 'Should intersect at (0.75, 0.75)',
|
|
);
|
|
expect(intersection.first == Vector2.all(0.75), true);
|
|
});
|
|
|
|
test('One pixel overlap in different angles', () {
|
|
final segmentA = LineSegment(Vector2.all(0), Vector2.all(1));
|
|
final segmentB = LineSegment(Vector2.all(0), Vector2(1, -1));
|
|
final intersection = segmentA.intersections(segmentB);
|
|
expect(
|
|
intersection.isNotEmpty,
|
|
true,
|
|
reason: 'Should have intersection at (0, 0)',
|
|
);
|
|
expect(intersection.first == Vector2.all(0), true);
|
|
});
|
|
|
|
test('One pixel parallel overlap in same angle', () {
|
|
final segmentA = LineSegment(Vector2.all(0), Vector2.all(1));
|
|
final segmentB = LineSegment(Vector2.all(1), Vector2.all(2));
|
|
final intersection = segmentA.intersections(segmentB);
|
|
expect(
|
|
intersection.isNotEmpty,
|
|
true,
|
|
reason: 'Should have intersection at (1, 1)',
|
|
);
|
|
expect(intersection.first == Vector2.all(1), true);
|
|
});
|
|
});
|
|
|
|
group('Line.intersections tests', () {
|
|
test('Simple line intersection', () {
|
|
const line1 = const Line(1, -1, 0);
|
|
const line2 = const Line(1, 1, 0);
|
|
final intersection = line1.intersections(line2);
|
|
expect(intersection.isNotEmpty, true, reason: 'Should have intersection');
|
|
expect(intersection.first == Vector2.all(0), true);
|
|
});
|
|
|
|
test('Lines with c value', () {
|
|
const line1 = const Line(1, 1, 1);
|
|
const line2 = const Line(1, -1, 1);
|
|
final intersection = line1.intersections(line2);
|
|
expect(intersection.isNotEmpty, true, reason: 'Should have intersection');
|
|
expect(intersection.first == Vector2(1, 0), true);
|
|
});
|
|
|
|
test('Does not catch parallel lines', () {
|
|
const line1 = const Line(1, 1, -3);
|
|
const line2 = const Line(1, 1, 6);
|
|
final intersection = line1.intersections(line2);
|
|
expect(
|
|
intersection.isEmpty,
|
|
true,
|
|
reason: 'Should not have intersection',
|
|
);
|
|
});
|
|
|
|
test('Does not catch same line', () {
|
|
const line1 = const Line(1, 1, 1);
|
|
const line2 = const Line(1, 1, 1);
|
|
final intersection = line1.intersections(line2);
|
|
expect(
|
|
intersection.isEmpty,
|
|
true,
|
|
reason: 'Should not have intersection',
|
|
);
|
|
});
|
|
});
|
|
|
|
group('LinearEquation.fromPoints tests', () {
|
|
test('Simple line from points', () {
|
|
final line = Line.fromPoints(Vector2.zero(), Vector2.all(1));
|
|
expect(line.a == 1.0, true, reason: 'a value is not correct');
|
|
expect(line.b == -1.0, true, reason: 'b value is not correct');
|
|
expect(line.c == 0.0, true, reason: 'c value is not correct');
|
|
});
|
|
|
|
test('Line not going through origo', () {
|
|
final line = Line.fromPoints(Vector2(-2, 0), Vector2(0, 2));
|
|
expect(line.a == 2.0, true, reason: 'a value is not correct');
|
|
expect(line.b == -2.0, true, reason: 'b value is not correct');
|
|
expect(line.c == -4.0, true, reason: 'c value is not correct');
|
|
});
|
|
|
|
test('Straight vertical line', () {
|
|
final line = Line.fromPoints(Vector2.all(1), Vector2(1, -1));
|
|
expect(line.a == -2.0, true, reason: 'a value is not correct');
|
|
expect(line.b == 0.0, true, reason: 'b value is not correct');
|
|
expect(line.c == -2.0, true, reason: 'c value is not correct');
|
|
});
|
|
|
|
test('Straight horizontal line', () {
|
|
final line = Line.fromPoints(Vector2.all(1), Vector2(2, 1));
|
|
expect(line.a == 0.0, true, reason: 'a value is not correct');
|
|
expect(line.b == -1.0, true, reason: 'b value is not correct');
|
|
expect(line.c == -1.0, true, reason: 'c value is not correct');
|
|
});
|
|
});
|
|
|
|
group('LineSegment.pointsAt tests', () {
|
|
test('Simple pointing', () {
|
|
final segment = LineSegment(Vector2.zero(), Vector2.all(1));
|
|
const line = const Line(1, 1, 3);
|
|
final isPointingAt = segment.pointsAt(line);
|
|
expect(isPointingAt, true, reason: 'Line should be pointed at');
|
|
});
|
|
|
|
test('Is not pointed at when crossed', () {
|
|
final segment = LineSegment(Vector2.zero(), Vector2.all(3));
|
|
const line = const Line(1, 1, 3);
|
|
final isPointingAt = segment.pointsAt(line);
|
|
expect(isPointingAt, false, reason: 'Line should not be pointed at');
|
|
});
|
|
|
|
test('Is not pointed at when parallel', () {
|
|
final segment = LineSegment(Vector2.zero(), Vector2(1, -1));
|
|
const line = const Line(1, 1, 3);
|
|
final isPointingAt = segment.pointsAt(line);
|
|
expect(isPointingAt, false, reason: 'Line should not be pointed at');
|
|
});
|
|
|
|
test('Horizonal line can be pointed at', () {
|
|
final segment = LineSegment(Vector2.zero(), Vector2.all(1));
|
|
const line = const Line(0, 1, 2);
|
|
final isPointingAt = segment.pointsAt(line);
|
|
expect(isPointingAt, true, reason: 'Line should be pointed at');
|
|
});
|
|
|
|
test('Vertical line can be pointed at', () {
|
|
final segment = LineSegment(Vector2.zero(), Vector2.all(1));
|
|
const line = const Line(1, 0, 2);
|
|
final isPointingAt = segment.pointsAt(line);
|
|
expect(isPointingAt, true, reason: 'Line should be pointed at');
|
|
});
|
|
});
|
|
|
|
group('Polygon intersections tests', () {
|
|
test('Simple polygon collision', () {
|
|
final polygonA = Polygon([
|
|
Vector2(2, 2),
|
|
Vector2(3, 1),
|
|
Vector2(2, 0),
|
|
Vector2(1, 1),
|
|
]);
|
|
final polygonB = Polygon([
|
|
Vector2(1, 2),
|
|
Vector2(2, 1),
|
|
Vector2(1, 0),
|
|
Vector2(0, 1),
|
|
]);
|
|
final intersections = geometry.intersections(polygonA, polygonB);
|
|
expect(
|
|
intersections.contains(Vector2(1.5, 0.5)),
|
|
true,
|
|
reason: 'Missed one intersection',
|
|
);
|
|
expect(
|
|
intersections.contains(Vector2(1.5, 1.5)),
|
|
true,
|
|
reason: 'Missed one intersection',
|
|
);
|
|
expect(
|
|
intersections.length == 2,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Collision on shared line segment', () {
|
|
final polygonA = Polygon([
|
|
Vector2(1, 1),
|
|
Vector2(1, 2),
|
|
Vector2(2, 2),
|
|
Vector2(2, 1),
|
|
]);
|
|
final polygonB = Polygon([
|
|
Vector2(2, 1),
|
|
Vector2(2, 2),
|
|
Vector2(3, 2),
|
|
Vector2(3, 1),
|
|
]);
|
|
final intersections = geometry.intersections(polygonA, polygonB);
|
|
expect(
|
|
intersections.containsAll([
|
|
Vector2(2.0, 2.0),
|
|
Vector2(2.0, 1.5),
|
|
Vector2(2.0, 1.0),
|
|
]),
|
|
true,
|
|
reason: 'Does not have all the correct intersection points',
|
|
);
|
|
expect(
|
|
intersections.length == 3,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('One point collision', () {
|
|
final polygonA = Polygon([
|
|
Vector2(1, 1),
|
|
Vector2(1, 2),
|
|
Vector2(2, 2),
|
|
Vector2(2, 1),
|
|
]);
|
|
final polygonB = Polygon([
|
|
Vector2(2, 2),
|
|
Vector2(2, 3),
|
|
Vector2(3, 3),
|
|
Vector2(3, 2),
|
|
]);
|
|
final intersections = geometry.intersections(polygonA, polygonB);
|
|
expect(
|
|
intersections.contains(Vector2(2.0, 2.0)),
|
|
true,
|
|
reason: 'Does not have all the correct intersection points',
|
|
);
|
|
expect(
|
|
intersections.length == 1,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Collision while no corners are inside the other body', () {
|
|
final polygonA = Polygon.fromDefinition(
|
|
[
|
|
Vector2(1, 1),
|
|
Vector2(1, -1),
|
|
Vector2(-1, -1),
|
|
Vector2(-1, 1),
|
|
],
|
|
position: Vector2.zero(),
|
|
size: Vector2(2, 4),
|
|
);
|
|
final polygonB = Polygon.fromDefinition(
|
|
[
|
|
Vector2(1, 1),
|
|
Vector2(1, -1),
|
|
Vector2(-1, -1),
|
|
Vector2(-1, 1),
|
|
],
|
|
position: Vector2.zero(),
|
|
size: Vector2(4, 2),
|
|
);
|
|
final intersections = geometry.intersections(polygonA, polygonB);
|
|
expect(
|
|
intersections.containsAll([
|
|
Vector2(1, 1),
|
|
Vector2(1, -1),
|
|
Vector2(-1, 1),
|
|
Vector2(-1, -1),
|
|
]),
|
|
true,
|
|
reason: 'Does not have all the correct intersection points',
|
|
);
|
|
expect(
|
|
intersections.length == 4,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Collision with advanced hitboxes in different quadrants', () {
|
|
final polygonA = Polygon([
|
|
Vector2(0, 0),
|
|
Vector2(-1, 1),
|
|
Vector2(0, 3),
|
|
Vector2(2, 2),
|
|
Vector2(1.5, 0.5),
|
|
]);
|
|
final polygonB = Polygon([
|
|
Vector2(-2, -2),
|
|
Vector2(-3, 0),
|
|
Vector2(-2, 3),
|
|
Vector2(1, 2),
|
|
Vector2(2, 1),
|
|
]);
|
|
final intersections = geometry.intersections(polygonA, polygonB);
|
|
intersections.containsAll([
|
|
Vector2(-0.2857142857142857, 2.4285714285714284),
|
|
Vector2(1.7500000000000002, 1.2500000000000002),
|
|
Vector2(1.5555555555555556, 0.6666666666666667),
|
|
Vector2(1.1999999999999997, 0.39999999999999997),
|
|
]);
|
|
expect(
|
|
intersections.length == 4,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
});
|
|
|
|
group('Rectangle intersections tests', () {
|
|
test('Simple intersection', () {
|
|
final rectangleA = Rectangle(
|
|
position: Vector2(4, 0),
|
|
size: Vector2.all(4),
|
|
);
|
|
final rectangleB = Rectangle(
|
|
position: Vector2.zero(),
|
|
size: Vector2.all(4),
|
|
);
|
|
final intersections = geometry.intersections(rectangleA, rectangleB);
|
|
expect(
|
|
intersections.containsAll([
|
|
Vector2(2, -2),
|
|
Vector2(2, 0),
|
|
Vector2(2, 2),
|
|
]),
|
|
true,
|
|
reason: 'Missed intersections',
|
|
);
|
|
expect(
|
|
intersections.length == 3,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
});
|
|
|
|
group('Circle intersections tests', () {
|
|
test('Simple collision', () {
|
|
final circleA = Circle.fromDefinition(
|
|
position: Vector2(4, 0),
|
|
size: Vector2.all(4),
|
|
);
|
|
final circleB = Circle.fromDefinition(
|
|
position: Vector2.zero(),
|
|
size: Vector2.all(4),
|
|
);
|
|
final intersections = geometry.intersections(circleA, circleB);
|
|
expect(
|
|
intersections.contains(Vector2(2, 0)),
|
|
true,
|
|
reason: 'Missed one intersection',
|
|
);
|
|
expect(
|
|
intersections.length == 1,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Two point collision', () {
|
|
final circleA = Circle.fromDefinition(
|
|
position: Vector2(3, 0),
|
|
size: Vector2.all(4),
|
|
);
|
|
final circleB = Circle.fromDefinition(
|
|
position: Vector2.zero(),
|
|
size: Vector2.all(4),
|
|
);
|
|
final intersections = geometry.intersections(circleA, circleB);
|
|
expect(
|
|
intersections.contains(Vector2(1.5, -1.3228756555322954)),
|
|
true,
|
|
reason: 'Missed one intersection',
|
|
);
|
|
expect(
|
|
intersections.contains(Vector2(1.5, 1.3228756555322954)),
|
|
true,
|
|
reason: 'Missed one intersection',
|
|
);
|
|
expect(
|
|
intersections.length == 2,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Same size and position', () {
|
|
final circleA = Circle.fromDefinition(
|
|
position: Vector2.all(3),
|
|
size: Vector2.all(4),
|
|
);
|
|
final circleB = Circle.fromDefinition(
|
|
position: Vector2.all(3),
|
|
size: Vector2.all(4),
|
|
);
|
|
final intersections = geometry.intersections(circleA, circleB);
|
|
expect(
|
|
intersections.containsAll([
|
|
Vector2(5, 3),
|
|
Vector2(3, 5),
|
|
Vector2(3, 1),
|
|
Vector2(1, 3),
|
|
]),
|
|
true,
|
|
reason: 'Missed intersections',
|
|
);
|
|
expect(
|
|
intersections.length == 4,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Not overlapping', () {
|
|
final circleA = Circle.fromDefinition(
|
|
position: Vector2.all(-1),
|
|
size: Vector2.all(4),
|
|
);
|
|
final circleB = Circle.fromDefinition(
|
|
position: Vector2.all(3),
|
|
size: Vector2.all(4),
|
|
);
|
|
final intersections = geometry.intersections(circleA, circleB);
|
|
expect(
|
|
intersections.isEmpty,
|
|
true,
|
|
reason: 'Should not have any intersections',
|
|
);
|
|
});
|
|
|
|
test('In third quadrant', () {
|
|
final circleA = Circle.fromDefinition(
|
|
position: Vector2.all(-1),
|
|
size: Vector2.all(2),
|
|
);
|
|
final circleB = Circle.fromDefinition(
|
|
position: Vector2.all(-2),
|
|
size: Vector2.all(2),
|
|
);
|
|
final intersections = geometry.intersections(circleA, circleB).toList();
|
|
expect(
|
|
intersections.any((v) => v.distanceTo(Vector2(-1, -2)) < 0.000001),
|
|
true,
|
|
);
|
|
expect(
|
|
intersections.any((v) => v.distanceTo(Vector2(-2, -1)) < 0.000001),
|
|
true,
|
|
);
|
|
expect(
|
|
intersections.length == 2,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('In different quadrants', () {
|
|
final circleA = Circle.fromDefinition(
|
|
position: Vector2.all(-1),
|
|
size: Vector2.all(4),
|
|
);
|
|
final circleB = Circle.fromDefinition(
|
|
position: Vector2.all(1),
|
|
size: Vector2.all(4),
|
|
);
|
|
final intersections = geometry.intersections(circleA, circleB).toList();
|
|
expect(
|
|
intersections.any((v) => v.distanceTo(Vector2(1, -1)) < 0.000001),
|
|
true,
|
|
);
|
|
expect(
|
|
intersections.any((v) => v.distanceTo(Vector2(-1, 1)) < 0.000001),
|
|
true,
|
|
);
|
|
expect(
|
|
intersections.length == 2,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
});
|
|
|
|
group('Circle-Polygon intersections tests', () {
|
|
test('Simple circle-polygon intersection', () {
|
|
final circle = Circle.fromDefinition(
|
|
position: Vector2.zero(),
|
|
size: Vector2.all(2),
|
|
);
|
|
final polygon = Polygon([
|
|
Vector2(1, 2),
|
|
Vector2(2, 1),
|
|
Vector2(1, 0),
|
|
Vector2(0, 1),
|
|
]);
|
|
final intersections = geometry.intersections(circle, polygon);
|
|
expect(
|
|
intersections.containsAll([Vector2(0, 1), Vector2(1, 0)]),
|
|
true,
|
|
reason: 'Missed intersections',
|
|
);
|
|
expect(
|
|
intersections.length == 2,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Single point circle-polygon intersection', () {
|
|
final circle = Circle.fromDefinition(
|
|
position: Vector2(-1, 1),
|
|
size: Vector2.all(2),
|
|
);
|
|
final polygon = Polygon([
|
|
Vector2(1, 2),
|
|
Vector2(2, 1),
|
|
Vector2(1, 0),
|
|
Vector2(0, 1),
|
|
]);
|
|
final intersections = geometry.intersections(circle, polygon);
|
|
expect(
|
|
intersections.contains(Vector2(0, 1)),
|
|
true,
|
|
reason: 'Missed intersections',
|
|
);
|
|
expect(
|
|
intersections.length == 1,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Four point circle-polygon intersection', () {
|
|
final circle = Circle.fromDefinition(
|
|
position: Vector2.all(1),
|
|
size: Vector2.all(2),
|
|
);
|
|
final polygon = Polygon([
|
|
Vector2(1, 2),
|
|
Vector2(2, 1),
|
|
Vector2(1, 0),
|
|
Vector2(0, 1),
|
|
]);
|
|
final intersections = geometry.intersections(circle, polygon);
|
|
expect(
|
|
intersections.containsAll([
|
|
Vector2(1, 2),
|
|
Vector2(2, 1),
|
|
Vector2(1, 0),
|
|
Vector2(0, 1),
|
|
]),
|
|
true,
|
|
reason: 'Missed intersections',
|
|
);
|
|
expect(
|
|
intersections.length == 4,
|
|
true,
|
|
reason: 'Wrong number of intersections',
|
|
);
|
|
});
|
|
|
|
test('Polygon within circle, no intersections', () {
|
|
final circle = Circle.fromDefinition(
|
|
position: Vector2.all(1),
|
|
size: Vector2.all(2.1),
|
|
);
|
|
final polygon = Polygon([
|
|
Vector2(1, 2),
|
|
Vector2(2, 1),
|
|
Vector2(1, 0),
|
|
Vector2(0, 1),
|
|
]);
|
|
final intersections = geometry.intersections(circle, polygon);
|
|
expect(
|
|
intersections.isEmpty,
|
|
true,
|
|
reason: 'Should not be any intersections',
|
|
);
|
|
});
|
|
});
|
|
}
|