Skip to content

Instantly share code, notes, and snippets.

@jFransham
Last active November 28, 2015 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jFransham/99ceae9ed49ca9b74ba7 to your computer and use it in GitHub Desktop.
Save jFransham/99ceae9ed49ca9b74ba7 to your computer and use it in GitHub Desktop.
// requires the 'graphics' package
use graphics::math::{Vec2d, Matrix2d};
fn transform(t: Matrix2d, e: [Vec2d; 2]) -> [Vec2d; 2] {
use graphics::math::transform_pos;
[
transform_pos(t, e[0]),
transform_pos(t, e[1]),
]
}
fn get_perpendicular(e: [Vec2d; 2]) -> Vec2d {
use graphics::math::{
perp,
sub,
};
perp(sub(e[0], e[1]))
}
fn collides_rect_rect(
(p0, rot0, w0, h0): (Vec2d, f64, f64, f64),
(p1, rot1, w1, h1): (Vec2d, f64, f64, f64)
) -> bool {
use graphics::math::{
transform_pos,
rotate_radians,
translate,
multiply,
scale,
dot,
};
use std::f64;
let (sclm0, sclm1) = (
scale(w0, h0),
scale(w1, h1)
);
let (rotm0, rotm1) = (
rotate_radians(rot0),
rotate_radians(rot1)
);
let (trnm0, trnm1) = (
translate(p0),
translate(p1)
);
let points0 = UNIT_POINTS.iter()
.map(|e| transform_pos(sclm0, *e))
.map(|e| transform_pos(rotm0, e))
.map(|e| transform_pos(trnm0, e))
.collect::<Vec<_>>();
let points1 = UNIT_POINTS.iter()
.map(|e| transform_pos(sclm1, *e))
.map(|e| transform_pos(rotm1, e))
.map(|e| transform_pos(trnm1, e))
.collect::<Vec<_>>();
// Do not need to scale or transform because we
// only need the perpendicular
UNIT_EDGES.iter()
.map(|e| transform(rotm0, *e))
.chain(
UNIT_EDGES.iter()
.map(|e| transform(rotm1, *e))
)
.map(get_perpendicular)
.map(|line| {
let l1 = line.clone();
(
points0.iter()
.map(move |p| dot(*p, line)),
points1.iter()
.map(move |p| dot(*p, l1))
)
})
.map(|(flatPoints0, flatPoints1)| {
fn min_max(acc: (f64, f64), cur: f64) -> (f64, f64) {
(acc.0.min(cur), acc.1.max(cur))
}
let (min0, max0) =
flatPoints0
.fold((f64::INFINITY, f64::NEG_INFINITY), min_max);
let (min1, max1) =
flatPoints1
.fold((f64::INFINITY, f64::NEG_INFINITY), min_max);
max0 >= min1 && max1 >= min0
})
.all(|b| b)
}
const UNIT_EDGES: [[Vec2d; 2]; 4] = [
[
[0.0, 0.0],
[0.0, 1.0],
],
[
[0.0, 1.0],
[1.0, 1.0],
],
[
[1.0, 1.0],
[1.0, 0.0],
],
[
[1.0, 0.0],
[0.0, 0.0],
],
];
const UNIT_POINTS: [Vec2d; 4] = [
[0.0, 0.0],
[0.0, 1.0],
[1.0, 1.0],
[1.0, 0.0],
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment