use crate::raise;
use crate::{PebblesError, PebblesErrorDetails};
use rand_distr::{Triangular, Distribution};
pub struct Rect {
pub x:i64,
pub y:i64,
pub width:i64,
pub height:i64,
}
impl Rect {
pub fn local_point(&self) -> Result<(i64, i64), PebblesError> {
let mut rng = rand::thread_rng();
let triangular_x = Triangular::new(0.0, self.width as f64, self.width as f64 / 2.0)
.or_else(|error| raise!(PebblesError::MathError, format!(
"Error while generating Triangular range: /
{}", error)))?;
let triangular_y = Triangular::new(0.0, self.height as f64, self.height as f64 / 2.0)
.or_else(|error| raise!(PebblesError::MathError, format!(
"Error while generating Triangular range: /
{}", error)))?;
Ok((triangular_x.sample(&mut rng) as i64, triangular_y.sample(&mut rng) as i64))
}
pub fn world_point(&self) -> Result<(i64, i64), PebblesError> {
let (x, y) = self.local_point()?;
Ok((self.x + x, self.y + y))
}
pub fn overlaps(&self, other: &Rect) -> bool {
let self_right = self.x + self.width;
let self_bottom = self.y + self.height;
let other_right = other.x + other.width;
let other_bottom = other.y + other.height;
if self.x < other_right && self_right > other.x && self.y < other_bottom && self_bottom > other.y {
return true;
}
false
}
}
impl std::fmt::Display for Rect {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{{x:{}, y:{}, width:{}, height:{}}}", self.x, self.y, self.width, self.height)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_local_point() {
let rect = Rect {
x: 0,
y: 0,
width: 10,
height: 10,
};
let result = rect.local_point();
assert!(result.is_ok());
let point = result.unwrap();
assert!(point.0 >= 0 && point.0 <= 10);
assert!(point.1 >= 0 && point.1 <= 10);
}
#[test]
fn test_world_point() {
let rect = Rect {
x: 5,
y: 5,
width: 10,
height: 10,
};
let result = rect.world_point();
assert!(result.is_ok());
let point = result.unwrap();
assert!(point.0 >= 5 && point.0 <= 15);
assert!(point.1 >= 5 && point.1 <= 15);
}
#[test]
fn test_overlaps() {
let rect1 = Rect { x: 0, y: 0, width: 10, height: 10 };
let rect2 = Rect { x: 5, y: 5, width: 10, height: 10 };
let rect3 = Rect { x: 20, y: 20, width: 10, height: 10 };
assert!(rect1.overlaps(&rect2), "Rect1 should overlap with Rect2");
assert!(!rect1.overlaps(&rect3), "Rect1 should not overlap with Rect3");
}
}