#[derive(Debug, Clone, Copy)]
pub struct Point2D {
x: f64,
y: f64,
}
impl Point2D {
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
pub fn x(&self) -> f64 {
self.x
}
pub fn y(&self) -> f64 {
self.y
}
}
#[derive(Debug, Clone, Copy)]
pub struct HalfSpace2D {
a: (f64, f64),
b: f64,
}
impl HalfSpace2D {
pub fn new(a: (f64, f64), b: f64) -> Self {
Self { a, b }
}
pub fn inside(&self, point: Point2D) -> bool {
self.a.0 * point.x + self.a.1 * point.y <= self.b
}
}
#[derive(Debug, Clone)]
pub struct ConvexPolytope2D {
pub(crate) half_spaces: Vec<HalfSpace2D>,
}
impl ConvexPolytope2D {
pub fn new(half_spaces: &[HalfSpace2D]) -> Self {
Self {
half_spaces: half_spaces.to_owned(),
}
}
pub fn inside(&self, point: Point2D) -> bool {
self.half_spaces
.iter()
.all(|half_space| half_space.inside(point))
}
pub fn violations(&self, point: Point2D) -> Vec<HalfSpace2D> {
self.half_spaces
.iter()
.filter_map(|half_space| {
if half_space.inside(point) {
None
} else {
Some(*half_space)
}
})
.collect()
}
pub fn half_spaces(&self) -> &[HalfSpace2D] {
&self.half_spaces
}
}