mod clipper;
pub use clipper::*;
mod path;
pub use path::*;
mod paths;
pub use paths::*;
use crate::cxx_bridge::clipper2_sys_cxx;
use crate::cxx_bridge::clipper2_sys_cxx::ClipperFillRule;
use crate::paths_blob::{pathd_to_blob, pathsd_to_blob, DEFAULT_PATHD_PRECISION};
use crate::{EndType, JoinType, LazyPaths64, PointInPolygonResult};
pub type PointD = crate::cxx_bridge::clipper2_sys_cxx::PD;
impl PointD {
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
}
impl PathD {
pub fn simplify(&self, epsilon: f64, is_open_path: bool) -> LazyPathsD {
let out = clipper2_sys_cxx::cxx_pathd_simplify(&pathd_to_blob(self), epsilon, is_open_path);
LazyPathsD::from_blob(out)
}
pub fn point_in_polygon(&self, point: PointD) -> PointInPolygonResult {
clipper2_sys_cxx::cxx_point_in_pathd(&pathd_to_blob(self), point.x, point.y).into()
}
pub fn to_path64(&self) -> LazyPaths64 {
let b =
clipper2_sys_cxx::cxx_pathd_to_path64(&pathd_to_blob(self), DEFAULT_PATHD_PRECISION);
LazyPaths64::from_blob(b)
}
}
impl PathsD {
pub fn simplify(&self, epsilon: f64, is_open_path: bool) -> LazyPathsD {
let out =
clipper2_sys_cxx::cxx_pathsd_simplify(&pathsd_to_blob(self), epsilon, is_open_path);
LazyPathsD::from_blob(out)
}
pub fn inflate(
&self,
delta: f64,
join_type: JoinType,
end_type: EndType,
miter_limit: f64,
precision: i32,
) -> LazyPathsD {
let out = clipper2_sys_cxx::cxx_pathsd_inflate(
&pathsd_to_blob(self),
delta,
join_type.into(),
end_type.into(),
miter_limit,
precision,
);
LazyPathsD::from_blob(out)
}
pub fn to_paths64(&self) -> LazyPaths64 {
let b =
clipper2_sys_cxx::cxx_pathsd_to_paths64(&pathsd_to_blob(self), DEFAULT_PATHD_PRECISION);
LazyPaths64::from_blob(b)
}
}
impl PathD {
pub fn minkowski_sum(&self, pattern: &PathD, is_closed: bool, precision: i32) -> LazyPathsD {
LazyPathsD::from_blob(clipper2_sys_cxx::cxx_pathd_minkowski_sum(
&pathd_to_blob(pattern),
&pathd_to_blob(self),
is_closed,
precision,
))
}
pub fn minkowski_diff(&self, pattern: &PathD, is_closed: bool, precision: i32) -> LazyPathsD {
LazyPathsD::from_blob(clipper2_sys_cxx::cxx_pathd_minkowski_diff(
&pathd_to_blob(pattern),
&pathd_to_blob(self),
is_closed,
precision,
))
}
}
impl PathsD {
pub fn minkowski_sum(
&self,
pattern: &PathD,
is_closed: bool,
precision: i32,
fillrule: ClipperFillRule,
) -> LazyPathsD {
LazyPathsD::from_blob(clipper2_sys_cxx::cxx_pathsd_minkowski_sum(
&pathd_to_blob(pattern),
&pathsd_to_blob(self),
is_closed,
precision,
fillrule,
))
}
pub fn minkowski_diff(
&self,
pattern: &PathD,
is_closed: bool,
precision: i32,
fillrule: ClipperFillRule,
) -> LazyPathsD {
LazyPathsD::from_blob(clipper2_sys_cxx::cxx_pathsd_minkowski_diff(
&pathd_to_blob(pattern),
&pathsd_to_blob(self),
is_closed,
precision,
fillrule,
))
}
}
impl PathD {
pub fn area(&self) -> f64 {
clipper2_sys_cxx::cxx_pathd_area(&pathd_to_blob(self))
}
}
impl PathsD {
pub fn area(&self) -> f64 {
clipper2_sys_cxx::cxx_pathsd_area(&pathsd_to_blob(self))
}
}
#[cfg(test)]
mod tests {
use super::{PathD, PointD};
#[test]
fn pathd_area_unit_square() {
let p = PathD::new(vec![
PointD::new(0.0, 0.0),
PointD::new(10.0, 0.0),
PointD::new(10.0, 10.0),
PointD::new(0.0, 10.0),
]);
assert!((p.area().abs() - 100.0).abs() < 1e-6);
}
#[test]
fn pathd_simplify_reduces_collinear() {
let p = PathD::new(vec![
PointD::new(0.0, 0.0),
PointD::new(5.0, 0.0),
PointD::new(10.0, 0.0),
PointD::new(10.0, 10.0),
PointD::new(0.0, 10.0),
]);
let s = p.simplify(1.0, false);
assert!(s.into_first_path().len() <= p.len());
}
}