Skip to content

Commit

Permalink
Native polygon intersection function to accept references that pyfunc…
Browse files Browse the repository at this point in the history
…tion cannot
  • Loading branch information
Cleptomania committed Mar 2, 2024
1 parent 2e04341 commit 4bea1d1
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
61 changes: 61 additions & 0 deletions src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,66 @@
use pyo3::prelude::*;

pub fn are_polygons_intersecting_native(
poly_a: &Vec<(f32, f32)>,
poly_b: &Vec<(f32, f32)>,
) -> bool {
// If either polygon is empty, we should just return False
if poly_a.is_empty() || poly_b.is_empty() {
return false;
}
let polygons = [poly_a, poly_b];
for polygon in &polygons {
for i1 in 0..polygon.len() {
let i2 = (i1 + 1) % polygon.len();
let projection_1 = polygon[i1];
let projection_2 = polygon[i2];

let normal = (
projection_2.1 - projection_1.1,
projection_1.0 - projection_2.0,
);

let mut min_a: Option<f32> = None;
let mut max_a: Option<f32> = None;
let mut min_b: Option<f32> = None;
let mut max_b: Option<f32> = None;

for point in polygons[0] {
let projected = normal.0 * point.0 + normal.1 * point.1;
match min_a {
Some(x) if projected < x => min_a = Some(projected),
Some(_x) => {}
None => min_a = Some(projected),
}
match max_a {
Some(x) if projected > x => max_a = Some(projected),
Some(_x) => {}
None => max_a = Some(projected),
}
}

for point in polygons[1] {
let projected = normal.0 * point.0 + normal.1 * point.1;
match min_b {
Some(x) if projected < x => min_b = Some(projected),
Some(_x) => {}
None => min_b = Some(projected),
}
match max_b {
Some(x) if projected > x => max_b = Some(projected),
Some(_x) => {}
None => max_b = Some(projected),
}
}

if max_a <= min_b || max_b <= min_a {
return false;
}
}
}
true
}

#[pyfunction]
pub fn are_polygons_intersecting(poly_a: Vec<(f32, f32)>, poly_b: Vec<(f32, f32)>) -> bool {
// If either polygon is empty, we should just return False
Expand Down
6 changes: 3 additions & 3 deletions src/sprite_list.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::geometry::are_polygons_intersecting;
use crate::geometry::are_polygons_intersecting_native;
use crate::hitbox::{HitBox, RotatableHitBox};
use pyo3::prelude::*;

Expand Down Expand Up @@ -72,7 +72,7 @@ pub fn check_for_collision_with_list(
panic!("unknown hitbox type");
};

let check_2 = are_polygons_intersecting(main_points.to_vec(), other_points);
let check_2 = are_polygons_intersecting_native(&main_points, &other_points);

if check_2 {
final_sprites.push(sprite2.to_object(py));
Expand Down Expand Up @@ -149,7 +149,7 @@ pub fn check_for_collision_with_lists(
panic!("unknown hitbox type");
};

let check_2 = are_polygons_intersecting(main_points.to_vec(), other_points);
let check_2 = are_polygons_intersecting_native(&main_points, &other_points);

if check_2 {
final_sprites.push(sprite2.to_object(py));
Expand Down

0 comments on commit 4bea1d1

Please sign in to comment.