math.vec: add rotate_around_* (cw/ccw) functions to vec.Vec2[T] (#23807)

This commit is contained in:
larpon 2025-02-26 02:46:18 +01:00 committed by GitHub
parent 537605a058
commit 4f98fe982c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 86 additions and 1 deletions

View File

@ -258,6 +258,23 @@ pub fn (v Vec2[T]) project(u Vec2[T]) Vec2[T] {
return u.mul_scalar(percent)
}
// rotate_around_cw returns the vector `v` rotated *clockwise* `radians` around an origin vector `o` in Cartesian space.
pub fn (v Vec2[T]) rotate_around_cw(o Vec2[T], radians f64) Vec2[T] {
return v.rotate_around_ccw(o, -radians)
}
// rotate_around_ccw returns the vector `v` rotated *counter-clockwise* `radians` around an origin vector `o` in Cartesian space.
pub fn (v Vec2[T]) rotate_around_ccw(o Vec2[T], radians f64) Vec2[T] {
s := math.sin(radians)
c := math.cos(radians)
dx := v.x - o.x
dy := v.y - o.y
return Vec2[T]{
x: T(c * dx - s * dy + o.x)
y: T(s * dx + c * dy + o.y)
}
}
// eq returns a bool indicating if the two vectors are equal.
@[inline]
pub fn (v Vec2[T]) eq(u Vec2[T]) bool {

View File

@ -1,4 +1,4 @@
import math { close, veryclose }
import math { close, radians, veryclose }
import math.vec
fn test_vec2_int() {
@ -160,3 +160,71 @@ fn test_vec2_angle_towards() {
}
}
}
fn test_vec2_rotate_around_cw() {
origin := vec.vec2(0.0, 0.0)
mut v := vec.vec2(0.0, 1.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, 1.0)
assert close(v.y, 0.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, 0.0)
assert close(v.y, -1.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, -1.0)
assert close(v.y, 0.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, 0.0)
assert close(v.y, 1.0)
}
fn test_vec2_rotate_around_ccw() {
origin := vec.vec2(0.0, 0.0)
mut v := vec.vec2(0.0, 1.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, -1.0)
assert close(v.y, 0.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, 0.0)
assert close(v.y, -1.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, 1.0)
assert close(v.y, 0.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, 0.0)
assert close(v.y, 1.0)
}
fn test_vec2_rotate_around_cw_2() {
origin := vec.vec2(1.0, 1.0)
mut v := vec.vec2(1.0, 2.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, 2.0)
assert close(v.y, 1.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, 1.0)
assert close(v.y, 0.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, 0.0)
assert close(v.y, 1.0)
v = v.rotate_around_cw(origin, radians(90))
assert close(v.x, 1.0)
assert close(v.y, 2.0)
}
fn test_vec2_rotate_around_ccw_2() {
origin := vec.vec2(-1.0, 1.0)
mut v := vec.vec2(-1.0, -1.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, 1.0)
assert close(v.y, 1.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, -1.0)
assert close(v.y, 3.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, -3.0)
assert close(v.y, 1.0)
v = v.rotate_around_ccw(origin, radians(90))
assert close(v.x, -1.0)
assert close(v.y, -1.0)
}