here_be_dragons/src/geometry.rs

103 lines
2.5 KiB
Rust
Raw Normal View History

2020-09-14 18:29:36 +00:00
//! Support function for 2D geometry
//!
/// Position on the map
#[derive(Default, PartialEq, Copy, Clone, Debug, Eq, Hash)]
pub struct Point {
pub x: usize,
pub y: usize
}
impl Point {
/// Create new point
pub fn new(x: usize, y: usize) -> Point {
Point {x, y}
}
2020-09-14 20:54:39 +00:00
/// Create new point from i32 coords
pub fn new_i32(x: i32, y: i32) -> Point {
Point::new(x as usize, y as usize)
}
2020-09-14 18:29:36 +00:00
/// Euclidean distance to a given point
pub fn distance_to(self, point: &Point) -> f32 {
let a = (self.x as f32 - point.x as f32).powf(2.0);
let b = (self.y as f32 - point.y as f32).powf(2.0);
(a + b).sqrt()
}
}
/// Rectangle region on the map
#[derive(PartialEq, Copy, Clone)]
pub struct Rect {
2020-09-15 20:33:18 +00:00
pub x1 : usize,
pub x2 : usize,
pub y1 : usize,
pub y2 : usize
2020-09-14 18:29:36 +00:00
}
impl Rect {
2020-09-15 20:33:18 +00:00
pub fn new(x: usize, y: usize, width: usize, height: usize) -> Rect {
2020-09-14 18:29:36 +00:00
Rect{x1:x, y1:y, x2:x+width, y2:y+height}
}
2020-09-15 20:33:18 +00:00
pub fn new_i32(x:i32, y: i32, width:i32, height:i32) -> Rect {
Rect::new(x as usize, y as usize, width as usize, height as usize)
}
2020-09-14 18:29:36 +00:00
/// Returns true if this overlaps with other
pub fn intersect(&self, other:&Rect) -> bool {
self.x1 <= other.x2 && self.x2 >= other.x1 && self.y1 <= other.y2 && self.y2 >= other.y1
}
2020-09-14 20:54:39 +00:00
pub fn center(&self) -> Point {
2020-09-15 20:33:18 +00:00
Point::new((self.x1 + self.x2)/2, (self.y1 + self.y2)/2)
}
pub fn width(&self) -> usize {
if self.x2 >= self.x1 {
self.x2 - self.x1
} else {
self.x1 - self.x2
}
}
pub fn height(&self) -> usize {
if self.y2 >= self.y1 {
self.y2 - self.y1
} else {
self.y1 - self.y2
}
2020-09-14 18:29:36 +00:00
}
}
/// ------------------------------------------------------------------------------------------------
/// Module unit tests
/// ------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_distance() {
let p1 = Point::new(10, 10);
let p2 = Point::new(14, 7);
let distance = p1.distance_to(&p2);
assert_eq!(distance, 5.0);
}
#[test]
fn test_intersect() {
let rect1 = Rect::new(10, 10, 40, 40);
let rect2 = Rect::new(30, 30, 60, 60);
assert!(rect1.intersect(&rect2));
}
2020-09-15 20:33:18 +00:00
#[test]
fn test_size() {
let rect1 = Rect::new(10, 10, 40, 30);
assert_eq!(rect1.width(), 40);
assert_eq!(rect1.height(), 30);
}
2020-09-14 18:29:36 +00:00
}