Skip to content

Commit ca2b6ee

Browse files
committed
Math updates. Renamed lerp functions, added quaternion_rotation
1 parent 64d824e commit ca2b6ee

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

python/arcade_accelerate/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ def patch_math(patches):
3636
patches["arcade.math"].rotate_point = arcade_accelerate.rotate_point
3737
patches["arcade.math"].clamp = arcade_accelerate.clamp
3838
patches["arcade.math"].lerp = arcade_accelerate.lerp
39-
patches["arcade.math"].lerp_vec = arcade_accelerate.lerp_vec
39+
patches["arcade.math"].lerp_2d = arcade_accelerate.lerp_2d
40+
patches["arcade.math"].lerp_3d = arcade_accelerate.lerp_3d
4041
patches["arcade.math"].lerp_angle = arcade_accelerate.lerp_angle
4142
patches["arcade.math"].get_distance = arcade_accelerate.get_distance
4243
patches["arcade.math"].get_angle_degrees = arcade_accelerate.get_angle_degrees
@@ -53,6 +54,7 @@ def patch_math(patches):
5354
arcade_accelerate.rand_vec_degree_spread
5455
)
5556
patches["arcade.math"].rand_vec_magnitude = arcade_accelerate.rand_vec_magnitude
57+
patches["arcade.math"].quaternion_rotation = arcade_accelerate.quaternion_rotation
5658

5759

5860
def patch_geometry(patches):

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ fn arcade_accelerate(_py: Python, m: &PyModule) -> PyResult<()> {
2020
m.add_function(wrap_pyfunction!(math::rotate_point, m)?)?;
2121
m.add_function(wrap_pyfunction!(math::clamp, m)?)?;
2222
m.add_function(wrap_pyfunction!(math::lerp, m)?)?;
23-
m.add_function(wrap_pyfunction!(math::lerp_vec, m)?)?;
23+
m.add_function(wrap_pyfunction!(math::lerp_2d, m)?)?;
24+
m.add_function(wrap_pyfunction!(math::lerp_3d, m)?)?;
2425
m.add_function(wrap_pyfunction!(math::lerp_angle, m)?)?;
2526
m.add_function(wrap_pyfunction!(math::get_distance, m)?)?;
2627
m.add_function(wrap_pyfunction!(math::get_angle_degrees, m)?)?;
@@ -33,6 +34,7 @@ fn arcade_accelerate(_py: Python, m: &PyModule) -> PyResult<()> {
3334
m.add_function(wrap_pyfunction!(math::rand_angle_spread_deg, m)?)?;
3435
m.add_function(wrap_pyfunction!(math::rand_vec_degree_spread, m)?)?;
3536
m.add_function(wrap_pyfunction!(math::rand_vec_magnitude, m)?)?;
37+
m.add_function(wrap_pyfunction!(math::quaternion_rotation, m)?)?;
3638
m.add_function(wrap_pyfunction!(geometry::are_polygons_intersecting, m)?)?;
3739
m.add_function(wrap_pyfunction!(geometry::is_point_in_polygon, m)?)?;
3840
m.add_function(wrap_pyfunction!(geometry::is_point_in_box, m)?)?;

src/math.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,19 @@ pub fn lerp(v1: f32, v2: f32, u: f32) -> f32 {
4141
}
4242

4343
#[pyfunction]
44-
pub fn lerp_vec(v1: (f32, f32), v2: (f32, f32), u: f32) -> (f32, f32) {
44+
pub fn lerp_2d(v1: (f32, f32), v2: (f32, f32), u: f32) -> (f32, f32) {
4545
(lerp(v1.0, v2.0, u), lerp(v1.1, v2.1, u))
4646
}
4747

48+
#[pyfunction]
49+
pub fn lerp_3d(v1: (f32, f32, f32), v2: (f32, f32, f32), u: f32) -> (f32, f32, f32) {
50+
(
51+
lerp(v1.0, v2.0, u),
52+
lerp(v1.1, v2.1, u),
53+
lerp(v1.2, v2.2, u),
54+
)
55+
}
56+
4857
#[pyfunction]
4958
pub fn lerp_angle(start_angle: f32, end_angle: f32, u: f32) -> f32 {
5059
let temp_start = start_angle % 360.0;
@@ -130,7 +139,7 @@ pub fn rand_on_line(pos1: (f32, f32), pos2: (f32, f32)) -> (f32, f32) {
130139
let mut rng = thread_rng();
131140
let u: f32 = rng.gen_range(0.0..1.0);
132141

133-
lerp_vec(pos1, pos2, u)
142+
lerp_2d(pos1, pos2, u)
134143
}
135144

136145
#[pyfunction]
@@ -164,6 +173,29 @@ pub fn rand_vec_magnitude(angle: f32, lo_magnitude: f32, hi_magnitude: f32) -> (
164173
vel.as_tuple()
165174
}
166175

176+
#[pyfunction]
177+
pub fn quaternion_rotation(
178+
axis: (f32, f32, f32),
179+
vector: (f32, f32, f32),
180+
angle: f32,
181+
) -> (f32, f32, f32) {
182+
let angle_rads = -angle.to_radians();
183+
let (c2, s2) = (f32::cos(angle_rads / 2.0), f32::sin(angle_rads / 2.0));
184+
185+
let (q0, q1, q2, q3) = (c2, s2 * axis.0, s2 * axis.1, s2 * axis.2);
186+
let (q0_2, q1_2, q2_2, q3_2) = (q0.powi(2), q1.powi(2), q2.powi(2), q3.powi(2));
187+
let (q01, q02, q03, q12, q13, q23) = (q0 * q1, q0 * q2, q0 * q3, q1 * q2, q1 * q3, q2 * q3);
188+
189+
let x = vector.0 * (q0_2 + q1_2 - q2_2 - q3_2)
190+
+ 2.0 * (vector.1 * (q12 - q03) + vector.2 * (q02 + q13));
191+
let y = vector.1 * (q0_2 - q1_2 + q2_2 - q3_2)
192+
+ 2.0 * (vector.0 * (q03 + q12) + vector.2 * (q23 - q01));
193+
let z = vector.2 * (q0_2 - q1_2 - q2_2 + q3_2)
194+
+ 2.0 * (vector.0 * (q13 + q02) + vector.1 * (q01 + q23));
195+
196+
(x, y, z)
197+
}
198+
167199
// This is only a subset of _Vec2 methods defined in arcade.math.py
168200
struct _Vec2 {
169201
x: f32,
@@ -262,14 +294,23 @@ mod tests {
262294
}
263295

264296
#[test]
265-
fn test_lerp_vec() {
266-
let mut result = lerp_vec((0.0, 2.0), (8.0, 4.0), 0.25);
297+
fn test_lerp_2d() {
298+
let mut result = lerp_2d((0.0, 2.0), (8.0, 4.0), 0.25);
267299
assert_eq!(result, (2.0, 2.5));
268300

269-
result = lerp_vec((0.0, 2.0), (8.0, 4.0), -0.25);
301+
result = lerp_2d((0.0, 2.0), (8.0, 4.0), -0.25);
270302
assert_eq!(result, (-2.0, 1.5));
271303
}
272304

305+
#[test]
306+
fn test_lerp_3d() {
307+
let mut result = lerp_3d((0.0, 2.0, 4.0), (8.0, 4.0, 8.0), 0.25);
308+
assert_eq!(result, (2.0, 2.5, 5.0));
309+
310+
result = lerp_3d((0.0, 2.0, 4.0), (8.0, 4.0, 8.0), -0.25);
311+
assert_eq!(result, (-2.0, 1.5, 3.0));
312+
}
313+
273314
#[test]
274315
fn test_lerp_angle_normal() {
275316
//normal

0 commit comments

Comments
 (0)