refactor: rotation on shapes

pull/87/head
RuiAlonso 4 years ago
parent a4f387edbb
commit def78bb56e

@ -5,8 +5,8 @@ import 'package:vector_math/vector_math_64.dart';
/// Calculates all [Vector2]s of a circumference. /// Calculates all [Vector2]s of a circumference.
/// ///
/// A circumference can be achieved by specifying a [center] and a [radius]. /// A circumference can be achieved by specifying a [center] and a [radius].
/// In addition, a semi-circle can be achieved by specifying its [angle] in /// In addition, a semi-circle can be achieved by specifying its [angle] and an
/// radians. /// [offsetAngle] (both in radians).
/// ///
/// The higher the [precision], the more [Vector2]s will be calculated; /// The higher the [precision], the more [Vector2]s will be calculated;
/// achieving a more rounded arc. /// achieving a more rounded arc.
@ -16,14 +16,15 @@ List<Vector2> calculateArc({
required Vector2 center, required Vector2 center,
required double radius, required double radius,
required double angle, required double angle,
double offsetAngle = 0,
int precision = 100, int precision = 100,
}) { }) {
final stepAngle = angle / (precision - 1); final stepAngle = angle / (precision - 1);
final points = <Vector2>[]; final points = <Vector2>[];
for (var i = 0; i < precision; i++) { for (var i = 0; i < precision; i++) {
final x = center.x + radius * math.cos(stepAngle * i); final x = center.x + radius * math.cos((stepAngle * i) + offsetAngle);
final y = center.y - radius * math.sin(stepAngle * i); final y = center.y - radius * math.sin((stepAngle * i) + offsetAngle);
final point = Vector2(x, y); final point = Vector2(x, y);
points.add(point); points.add(point);

@ -1,6 +1,5 @@
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'package:flame/extensions.dart';
import 'package:flame_forge2d/flame_forge2d.dart'; import 'package:flame_forge2d/flame_forge2d.dart';
import 'package:geometry/geometry.dart'; import 'package:geometry/geometry.dart';
@ -13,12 +12,14 @@ class ArcShape extends ChainShape {
required this.center, required this.center,
required this.arcRadius, required this.arcRadius,
required this.angle, required this.angle,
this.rotation = 0,
}) { }) {
createChain( createChain(
calculateArc( calculateArc(
center: center, center: center,
radius: arcRadius, radius: arcRadius,
angle: angle, angle: angle,
offsetAngle: rotation,
), ),
); );
} }
@ -35,19 +36,19 @@ class ArcShape extends ChainShape {
/// For example, two pi returns a complete circumference. /// For example, two pi returns a complete circumference.
final double angle; final double angle;
/// Rotates the arc by a given [angle] in radians. /// Angle in radians to rotate the arc around its [center].
void rotate(double angle) { final double rotation;
vertices.map((vector) => vector..rotate(angle)).toList();
}
ArcShape copyWith({ ArcShape copyWith({
Vector2? center, Vector2? center,
double? arcRadius, double? arcRadius,
double? angle, double? angle,
double? rotation,
}) => }) =>
ArcShape( ArcShape(
center: center ?? this.center, center: center ?? this.center,
arcRadius: arcRadius ?? this.arcRadius, arcRadius: arcRadius ?? this.arcRadius,
angle: angle ?? this.angle, angle: angle ?? this.angle,
rotation: rotation ?? this.rotation,
); );
} }

@ -43,7 +43,6 @@ void main() {
center: Vector2.all(10), center: Vector2.all(10),
arcRadius: 15, arcRadius: 15,
angle: 2 * math.pi, angle: 2 * math.pi,
rotation: math.pi,
); );
final arcShapeCopied = ArcShape( final arcShapeCopied = ArcShape(
center: Vector2.zero(), center: Vector2.zero(),
@ -53,7 +52,6 @@ void main() {
center: Vector2.all(10), center: Vector2.all(10),
arcRadius: 15, arcRadius: 15,
angle: 2 * math.pi, angle: 2 * math.pi,
rotation: math.pi,
); );
for (var index = 0; index < arcShapeCopied.vertices.length; index++) { for (var index = 0; index < arcShapeCopied.vertices.length; index++) {

@ -22,23 +22,30 @@ void main() {
); );
}); });
test('returns vertices rotated', () { group('rotate', () {
const rotationAngle = 2 * math.pi; test('returns vertices rotated', () {
const rotationAngle = 2 * math.pi;
final controlPoints = [
Vector2(0, 0),
Vector2(10, 0),
Vector2(0, 10),
Vector2(10, 10),
];
final bezierCurveShape = BezierCurveShape( final bezierCurveShape = BezierCurveShape(
controlPoints: controlPoints, controlPoints: controlPoints,
);
final bezierCurveShapeRotated = BezierCurveShape(
controlPoints: controlPoints,
rotation: rotationAngle,
);
for (var index = 0; index < bezierCurveShape.vertices.length; index++) {
expect(
bezierCurveShape.vertices[index]..rotate(rotationAngle),
equals(bezierCurveShapeRotated.vertices[index]),
); );
} final bezierCurveShapeRotated = BezierCurveShape(
controlPoints: controlPoints,
)..rotate(rotationAngle);
for (var index = 0; index < bezierCurveShape.vertices.length; index++) {
expect(
bezierCurveShape.vertices[index]..rotate(rotationAngle),
equals(bezierCurveShapeRotated.vertices[index]),
);
}
});
}); });
}); });
} }

@ -17,26 +17,27 @@ void main() {
); );
}); });
test('returns vertices rotated', () { group('rotate', () {
const rotationAngle = 2 * math.pi; test('returns vertices rotated', () {
final ellipseShape = EllipseShape( const rotationAngle = 2 * math.pi;
center: Vector2.zero(), final ellipseShape = EllipseShape(
majorRadius: 10, center: Vector2.zero(),
minorRadius: 8, majorRadius: 10,
); minorRadius: 8,
final ellipseShapeRotated = EllipseShape(
center: Vector2.zero(),
majorRadius: 10,
minorRadius: 8,
rotation: rotationAngle,
);
for (var index = 0; index < ellipseShape.vertices.length; index++) {
expect(
ellipseShape.vertices[index]..rotate(rotationAngle),
equals(ellipseShapeRotated.vertices[index]),
); );
} final ellipseShapeRotated = EllipseShape(
center: Vector2.zero(),
majorRadius: 10,
minorRadius: 8,
)..rotate(rotationAngle);
for (var index = 0; index < ellipseShape.vertices.length; index++) {
expect(
ellipseShape.vertices[index]..rotate(rotationAngle),
equals(ellipseShapeRotated.vertices[index]),
);
}
});
}); });
group('copyWith', () { group('copyWith', () {

Loading…
Cancel
Save