Skip to content

Commit

Permalink
circle, region cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ryan-williams committed Oct 9, 2023
1 parent 7f331f8 commit d7f7461
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 102 deletions.
124 changes: 91 additions & 33 deletions src/circle.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
use std::{fmt::{Display, self}, ops::{Mul, Add, Neg, Div, Sub}, f64::consts::PI};
use std::{
f64::consts::PI,
fmt::{self, Display},
ops::{Add, Div, Mul, Neg, Sub},
};

use crate::{
coord_getter::{coord_getter, CoordGetter},
dual::{Dual, D},
ellipses::xyrr::{UnitCircleGap, XYRR},
intersect::Intersect,
math::{is_normal::IsNormal, recip::Recip},
r2::R2,
rotate::{Rotate as _Rotate, RotateArg},
shape::{AreaArg, Duals, Shape, Shapes},
sqrt::Sqrt,
to::To,
transform::Transform::{self, Rotate, Scale, ScaleXY, Translate},
transform::{CanTransform, Projection},
};
use derive_more::From;
use log::debug;
use serde::{Deserialize, Serialize};
use tsify::Tsify;
use crate::{
dual::{D, Dual},
r2::R2, rotate::{Rotate as _Rotate, RotateArg}, shape::{Duals, Shape, Shapes, AreaArg}, transform::{Projection, CanTransform}, transform::Transform::{Rotate, Scale, ScaleXY, Translate, self}, ellipses::xyrr::{XYRR, UnitCircleGap}, sqrt::Sqrt, math::{is_normal::IsNormal, recip::Recip}, to::To, intersect::Intersect, coord_getter::{CoordGetter, coord_getter}
};

#[derive(Debug, Clone, Copy, From, PartialEq, Tsify, Serialize, Deserialize)]
pub struct Circle<D> {
Expand Down Expand Up @@ -35,7 +49,7 @@ impl Circle<f64> {
let uy = (y - self.c.y) / self.r;
let uy2 = uy * uy;
if uy2 > 1. {
return vec![]
return vec![];
}
let ux1 = (1. - uy2).sqrt();
let ux0 = -ux1;
Expand All @@ -53,7 +67,10 @@ impl Circle<f64> {

impl Circle<D> {
pub fn v(&self) -> Circle<f64> {
Circle { c: self.c.v(), r: self.r.v() }
Circle {
c: self.c.v(),
r: self.r.v(),
}
}
pub fn n(&self) -> usize {
self.c.x.d().len()
Expand All @@ -79,14 +96,15 @@ pub trait UnitIntersectionsArg
+ Mul<f64, Output = Self>
+ Div<Output = Self>
+ Div<f64, Output = Self>
{}
{
}

impl UnitIntersectionsArg for f64 {}
impl UnitIntersectionsArg for Dual {}

impl<D: UnitIntersectionsArg> Circle<D>
where
f64: Add<D, Output = D>
f64: Add<D, Output = D>,
{
pub fn unit_intersections(&self) -> Vec<R2<D>> {
let cx = self.c.x.clone();
Expand Down Expand Up @@ -122,19 +140,33 @@ where
};
let mut intersections: Vec<R2<D>> = Vec::new();
if x0.is_normal() && y0.is_normal() {
intersections.push(R2 { x: x0.clone(), y: y0.clone() });
intersections.push(R2 {
x: x0.clone(),
y: y0.clone(),
});
}
if x1.is_normal() && y1.is_normal() {
intersections.push(R2 { x: x1.clone(), y: y1.clone() });
intersections.push(R2 {
x: x1.clone(),
y: y1.clone(),
});
}
debug!("Circle::unit_intserctions: {}, {} intersections: {:?}", self, intersections.len(), intersections);
debug!(
"Circle::unit_intserctions: {}, {} intersections: {:?}",
self,
intersections.len(),
intersections
);
intersections
}
}

impl<O, I: To<O>> To<Circle<O>> for Circle<I> {
fn to(self) -> Circle<O> {
Circle { c: self.c.to(), r: self.r.to() }
Circle {
c: self.c.to(),
r: self.r.to(),
}
}
}

Expand All @@ -145,15 +177,18 @@ impl<D: Clone> To<XYRR<D>> for Circle<D> {
r: R2 {
x: self.r.clone(),
y: self.r.clone(),
}
},
}
}
}

impl Mul<R2<f64>> for R2<Dual> {
type Output = R2<Dual>;
fn mul(self, rhs: R2<f64>) -> Self::Output {
R2 { x: self.x * rhs.x, y: self.y * rhs.y }
R2 {
x: self.x * rhs.x,
y: self.y * rhs.y,
}
}
}
pub trait TransformD
Expand All @@ -174,36 +209,39 @@ impl TransformR2<f64> for R2<f64> {}
impl TransformR2<Dual> for R2<Dual> {}

impl<D: TransformD> CanTransform<D> for Circle<D>
where R2<D>: TransformR2<D>,
where
R2<D>: TransformR2<D>,
{
type Output = Shape<D>;
fn transform(&self, transform: &Transform<D>) -> Shape<D> {
match transform {
Translate(v) =>
Circle {
c: self.c.clone() + v.clone(),
r: self.r.clone()
}.into(),
Translate(v) => Circle {
c: self.c.clone() + v.clone(),
r: self.r.clone(),
}
.into(),
Scale(s) => {
let r = &self.r;
Circle {
c: self.c.clone() * s.clone(),
r: r.clone() * s.clone(),
}.into()
}
.into()
}
ScaleXY(s) => {
let r = &self.r;
XYRR {
c: self.c.clone() * s.clone(),
r: s * r.clone(),
}.into()
},
}
.into()
}
Rotate(a) => {
// let c = rotate::Rotate::rotate(&self.c.clone(), a);
let c = self.c.clone().rotate(a);
let r = self.r.clone();
Circle { c, r, }.into()
},
Circle { c, r }.into()
}
}
}
}
Expand Down Expand Up @@ -232,7 +270,10 @@ impl<D: Clone> Circle<D> {
pub fn xyrr(&self) -> XYRR<D> {
XYRR {
c: self.c.clone(),
r: R2 { x: self.r.clone(), y: self.r.clone() },
r: R2 {
x: self.r.clone(),
y: self.r.clone(),
},
}
}
}
Expand Down Expand Up @@ -298,17 +339,26 @@ mod tests {

use super::*;

use crate::{intersect::Intersect, duals::{D, Z}};
use crate::{
duals::{D, Z},
intersect::Intersect,
};

pub fn r2(x: f64, dx: Vec<f64>, y: f64, dy: Vec<f64>) -> R2<D> {
R2 { x: Dual::new(x, dx), y: Dual::new(y, dy) }
R2 {
x: Dual::new(x, dx),
y: Dual::new(y, dy),
}
}

fn swap_v(v: Vec<f64>) -> Vec<f64> {
[&v[3..], &v[..3]].concat()
}
fn swap(p: R2<Dual>) -> R2<Dual> {
R2 { x: Dual::new(p.x.v(), swap_v(p.x.d())), y: Dual::new(p.y.v(), swap_v(p.y.d())) }
R2 {
x: Dual::new(p.x.v(), swap_v(p.x.d())),
y: Dual::new(p.y.v(), swap_v(p.y.d())),
}
}

fn check(c0: Circle<f64>, c1: Circle<f64>, expected0: R2<D>, expected1: R2<D>) {
Expand Down Expand Up @@ -337,9 +387,17 @@ mod tests {
let c1 = c1 * scale + R2 { x: dx, y: dy };
let R2 { x: e0x, y: e0y } = expected0.clone();
let R2 { x: e1x, y: e1y } = expected1.clone();
let transform = |d: Dual, o: i64| Dual::new(d.v() * (scale as f64) + (o as f64), d.d().clone());
let e0 = R2 { x: transform(e0x, dx), y: transform(e0y, dy) };
let e1 = R2 { x: transform(e1x, dx), y: transform(e1y, dy) };
let transform = |d: Dual, o: i64| {
Dual::new(d.v() * (scale as f64) + (o as f64), d.d().clone())
};
let e0 = R2 {
x: transform(e0x, dx),
y: transform(e0y, dy),
};
let e1 = R2 {
x: transform(e1x, dx),
y: transform(e1y, dy),
};
check(c0, c1, e0.clone(), e1.clone());
// The "dual" circles were created in the opposite order, swap the first and last 3 derivative components.
check(c1, c0, swap(e0), swap(e1));
Expand Down
2 changes: 1 addition & 1 deletion src/hull.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ where R2<D>: To<R2<f64>>,
{
pub fn area(&self) -> D {
let polygon_area = Region::polygon_area(&self);
let secant_area = Region::secant_area("", &self, &self.0.iter().map(|s| s.edge.borrow().set_idx()).collect());
let secant_area = Region::secant_area(&self);
polygon_area + secant_area
}
}
Loading

0 comments on commit d7f7461

Please sign in to comment.