Skip to content

Commit d197870

Browse files
authored
feat: Add vector projection and inversion (#1787)
Adding projection, ìnvert and inverted to the vector extension.
1 parent c7c4480 commit d197870

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

Diff for: packages/flame/lib/src/extensions/vector2.dart

+20
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,26 @@ extension Vector2Extension on Vector2 {
8080
}
8181
}
8282

83+
/// Project this onto [other].
84+
///
85+
/// [other] needs to have a length > 0;
86+
/// If [out] is specified, it will be used to provide the result.
87+
Vector2 projection(Vector2 other, {Vector2? out}) {
88+
assert(other.length2 > 0, 'other needs to have a length > 0');
89+
final dotProduct = dot(other);
90+
final result = (out?..setFrom(other)) ?? other.clone();
91+
return result..scale(dotProduct / other.length2);
92+
}
93+
94+
/// Inverts the vector.
95+
void invert() {
96+
x *= -1;
97+
y *= -1;
98+
}
99+
100+
/// Returns the inverse of this vector.
101+
Vector2 inverted() => Vector2(-x, -y);
102+
83103
/// Smoothly moves this [Vector2] in the direction [target] by a displacement
84104
/// given by a distance [ds] in that direction.
85105
///

Diff for: packages/flame/test/extensions/vector2_test.dart

+55
Original file line numberDiff line numberDiff line change
@@ -208,4 +208,59 @@ void main() {
208208
expectDouble(position.screenAngle(), math.pi / 2);
209209
});
210210
});
211+
212+
group('projection', () {
213+
test('Project onto longer vector', () {
214+
final u = Vector2(5, 2);
215+
final v = Vector2(10, 0);
216+
final result = u.projection(v);
217+
expect(result, Vector2(5, 0));
218+
});
219+
220+
test('Project onto shorter vector', () {
221+
final u = Vector2(5, 2);
222+
final v = Vector2(2, 0);
223+
final result = u.projection(v);
224+
expect(result, Vector2(5, 0));
225+
});
226+
227+
test('Project onto vector in other direction', () {
228+
final u = Vector2(5, 2);
229+
final v = Vector2(-10, 0);
230+
final result = u.projection(v);
231+
expect(result, Vector2(5, 0));
232+
});
233+
234+
test('Project onto vector with out', () {
235+
final out = Vector2.zero();
236+
final u = Vector2(5, 2);
237+
final v = Vector2(-10, 0);
238+
final result = u.projection(v, out: out);
239+
expect(result, Vector2(5, 0));
240+
expect(out, Vector2(5, 0));
241+
});
242+
243+
test('Project onto vector with out as sane return and argument', () {
244+
var out = Vector2.zero();
245+
final u = Vector2(5, 2);
246+
final v = Vector2(-10, 0);
247+
out = u.projection(v, out: out);
248+
expect(out, Vector2(5, 0));
249+
});
250+
});
251+
252+
group('inversion', () {
253+
test('invert', () {
254+
final v = Vector2.all(1);
255+
v.invert();
256+
expect(v, Vector2.all(-1));
257+
});
258+
259+
test('inverted', () {
260+
final v = Vector2.all(1);
261+
final w = v.inverted();
262+
expect(v, Vector2.all(1));
263+
expect(w, Vector2.all(-1));
264+
});
265+
});
211266
}

0 commit comments

Comments
 (0)