mirror of https://codeberg.org/topola/topola.git
guide: Return Err(...) instead of panicking
This commit is contained in:
parent
087d1deea0
commit
177b8cb231
10
src/draw.rs
10
src/draw.rs
|
|
@ -76,7 +76,7 @@ impl<'a> Draw<'a> {
|
|||
fn finish_in_dot(&mut self, head: Head, into: DotIndex, width: f64) -> Result<(), ()> {
|
||||
let tangent = self
|
||||
.guide(&Default::default())
|
||||
.head_into_dot_segment(&head, into, width);
|
||||
.head_into_dot_segment(&head, into, width)?;
|
||||
let head = self.extend_head(head, tangent.start_point())?;
|
||||
|
||||
let net = self.layout.primitive(head.dot()).weight().net;
|
||||
|
|
@ -98,7 +98,7 @@ impl<'a> Draw<'a> {
|
|||
let to_cw = self.guide(&Default::default()).head_cw(&to_head).unwrap();
|
||||
let tangent = self
|
||||
.guide(&Default::default())
|
||||
.head_around_bend_segment(&head, into_bend, to_cw, width);
|
||||
.head_around_bend_segment(&head, into_bend, to_cw, width)?;
|
||||
|
||||
let head = self.extend_head(head, tangent.start_point())?;
|
||||
let _to_head = self.extend_head(to_head, tangent.end_point())?;
|
||||
|
|
@ -119,7 +119,7 @@ impl<'a> Draw<'a> {
|
|||
) -> Result<SegbendHead, ()> {
|
||||
let mut tangents = self
|
||||
.guide(&Default::default())
|
||||
.head_around_dot_segments(&head, around, width);
|
||||
.head_around_dot_segments(&head, around, width)?;
|
||||
let mut dirs = [true, false];
|
||||
|
||||
if tangents.1.euclidean_length() < tangents.0.euclidean_length() {
|
||||
|
|
@ -154,7 +154,7 @@ impl<'a> Draw<'a> {
|
|||
) -> Result<SegbendHead, ()> {
|
||||
let mut tangents = self
|
||||
.guide(&Default::default())
|
||||
.head_around_bend_segments(&head, around, width);
|
||||
.head_around_bend_segments(&head, around, width)?;
|
||||
let mut dirs = [true, false];
|
||||
|
||||
if tangents.1.euclidean_length() < tangents.0.euclidean_length() {
|
||||
|
|
@ -206,7 +206,7 @@ impl<'a> Draw<'a> {
|
|||
|
||||
let alternate_tangent = self
|
||||
.guide(&Default::default())
|
||||
.head_around_dot_segment(&prev_head, around, cw, 5.0);
|
||||
.head_around_dot_segment(&prev_head, around, cw, 5.0)?;
|
||||
|
||||
let segbend_dot_pos = self.layout.primitive(head.segbend.dot).weight().circle.pos;
|
||||
|
||||
|
|
|
|||
23
src/guide.rs
23
src/guide.rs
|
|
@ -23,7 +23,12 @@ impl<'a, 'b> Guide<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn head_into_dot_segment(&self, head: &Head, into: DotIndex, width: f64) -> Line {
|
||||
pub fn head_into_dot_segment(
|
||||
&self,
|
||||
head: &Head,
|
||||
into: DotIndex,
|
||||
width: f64,
|
||||
) -> Result<Line, ()> {
|
||||
let from_circle = self.head_circle(head, width);
|
||||
let to_circle = Circle {
|
||||
pos: self.layout.primitive(into).weight().circle.pos,
|
||||
|
|
@ -39,14 +44,14 @@ impl<'a, 'b> Guide<'a, 'b> {
|
|||
head: &Head,
|
||||
around: DotIndex,
|
||||
width: f64,
|
||||
) -> (Line, Line) {
|
||||
) -> Result<(Line, Line), ()> {
|
||||
let from_circle = self.head_circle(head, width);
|
||||
let to_circle = self.dot_circle(around, width);
|
||||
|
||||
let from_cw = self.head_cw(head);
|
||||
let tangents: Vec<Line> =
|
||||
math::tangent_segments(from_circle, from_cw, to_circle, None).collect();
|
||||
(tangents[0], tangents[1])
|
||||
math::tangent_segments(from_circle, from_cw, to_circle, None)?.collect();
|
||||
Ok((tangents[0], tangents[1]))
|
||||
}
|
||||
|
||||
pub fn head_around_dot_segment(
|
||||
|
|
@ -55,7 +60,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
|||
around: DotIndex,
|
||||
cw: bool,
|
||||
width: f64,
|
||||
) -> Line {
|
||||
) -> Result<Line, ()> {
|
||||
let from_circle = self.head_circle(head, width);
|
||||
let to_circle = self.dot_circle(around, width);
|
||||
|
||||
|
|
@ -68,14 +73,14 @@ impl<'a, 'b> Guide<'a, 'b> {
|
|||
head: &Head,
|
||||
around: BendIndex,
|
||||
width: f64,
|
||||
) -> (Line, Line) {
|
||||
) -> Result<(Line, Line), ()> {
|
||||
let from_circle = self.head_circle(head, width);
|
||||
let to_circle = self.bend_circle(around, width);
|
||||
|
||||
let from_cw = self.head_cw(head);
|
||||
let tangents: Vec<Line> =
|
||||
math::tangent_segments(from_circle, from_cw, to_circle, None).collect();
|
||||
(tangents[0], tangents[1])
|
||||
math::tangent_segments(from_circle, from_cw, to_circle, None)?.collect();
|
||||
Ok((tangents[0], tangents[1]))
|
||||
}
|
||||
|
||||
pub fn head_around_bend_segment(
|
||||
|
|
@ -84,7 +89,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
|||
around: BendIndex,
|
||||
cw: bool,
|
||||
width: f64,
|
||||
) -> Line {
|
||||
) -> Result<Line, ()> {
|
||||
let from_circle = self.head_circle(head, width);
|
||||
let to_circle = self.bend_circle(around, width);
|
||||
|
||||
|
|
|
|||
40
src/math.rs
40
src/math.rs
|
|
@ -25,38 +25,38 @@ impl Sub for Circle {
|
|||
}
|
||||
}
|
||||
|
||||
fn _tangent(center: Point, r1: f64, r2: f64) -> CanonicalLine {
|
||||
fn _tangent(center: Point, r1: f64, r2: f64) -> Result<CanonicalLine, ()> {
|
||||
let epsilon = 1e-9;
|
||||
let dr = r2 - r1;
|
||||
let norm = center.x() * center.x() + center.y() * center.y();
|
||||
let discriminant = norm - dr * dr;
|
||||
|
||||
if discriminant < -epsilon {
|
||||
panic!();
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let sqrt_discriminant = f64::sqrt(f64::abs(discriminant));
|
||||
|
||||
CanonicalLine {
|
||||
Ok(CanonicalLine {
|
||||
a: (center.x() * dr + center.y() * sqrt_discriminant) / norm,
|
||||
b: (center.y() * dr - center.x() * sqrt_discriminant) / norm,
|
||||
c: r1,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn _tangents(circle1: Circle, circle2: Circle) -> [CanonicalLine; 4] {
|
||||
fn _tangents(circle1: Circle, circle2: Circle) -> Result<[CanonicalLine; 4], ()> {
|
||||
let mut tgs: [CanonicalLine; 4] = [
|
||||
_tangent((circle2 - circle1).pos, -circle1.r, -circle2.r),
|
||||
_tangent((circle2 - circle1).pos, -circle1.r, circle2.r),
|
||||
_tangent((circle2 - circle1).pos, circle1.r, -circle2.r),
|
||||
_tangent((circle2 - circle1).pos, circle1.r, circle2.r),
|
||||
_tangent((circle2 - circle1).pos, -circle1.r, -circle2.r)?,
|
||||
_tangent((circle2 - circle1).pos, -circle1.r, circle2.r)?,
|
||||
_tangent((circle2 - circle1).pos, circle1.r, -circle2.r)?,
|
||||
_tangent((circle2 - circle1).pos, circle1.r, circle2.r)?,
|
||||
];
|
||||
|
||||
for tg in tgs.iter_mut() {
|
||||
tg.c -= tg.a * circle1.pos.x() + tg.b * circle1.pos.y();
|
||||
}
|
||||
|
||||
return tgs;
|
||||
Ok(tgs)
|
||||
}
|
||||
|
||||
fn cast_point_to_canonical_line(pt: Point, line: CanonicalLine) -> Point {
|
||||
|
|
@ -69,10 +69,10 @@ fn cast_point_to_canonical_line(pt: Point, line: CanonicalLine) -> Point {
|
|||
.into();
|
||||
}
|
||||
|
||||
fn tangent_point_pairs(circle1: Circle, circle2: Circle) -> [(Point, Point); 4] {
|
||||
let tgs = _tangents(circle1, circle2);
|
||||
fn tangent_point_pairs(circle1: Circle, circle2: Circle) -> Result<[(Point, Point); 4], ()> {
|
||||
let tgs = _tangents(circle1, circle2)?;
|
||||
|
||||
[
|
||||
Ok([
|
||||
(
|
||||
cast_point_to_canonical_line(circle1.pos, tgs[0]),
|
||||
cast_point_to_canonical_line(circle2.pos, tgs[0]),
|
||||
|
|
@ -89,7 +89,7 @@ fn tangent_point_pairs(circle1: Circle, circle2: Circle) -> [(Point, Point); 4]
|
|||
cast_point_to_canonical_line(circle1.pos, tgs[3]),
|
||||
cast_point_to_canonical_line(circle2.pos, tgs[3]),
|
||||
),
|
||||
]
|
||||
])
|
||||
}
|
||||
|
||||
pub fn tangent_segments(
|
||||
|
|
@ -97,8 +97,8 @@ pub fn tangent_segments(
|
|||
cw1: Option<bool>,
|
||||
circle2: Circle,
|
||||
cw2: Option<bool>,
|
||||
) -> impl Iterator<Item = Line> {
|
||||
tangent_point_pairs(circle1, circle2)
|
||||
) -> Result<impl Iterator<Item = Line>, ()> {
|
||||
Ok(tangent_point_pairs(circle1, circle2)?
|
||||
.into_iter()
|
||||
.filter_map(move |tangent_point_pair| {
|
||||
if let Some(cw1) = cw1 {
|
||||
|
|
@ -120,7 +120,7 @@ pub fn tangent_segments(
|
|||
}
|
||||
|
||||
Some(Line::new(tangent_point_pair.0, tangent_point_pair.1))
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn tangent_segment(
|
||||
|
|
@ -128,8 +128,10 @@ pub fn tangent_segment(
|
|||
cw1: Option<bool>,
|
||||
circle2: Circle,
|
||||
cw2: Option<bool>,
|
||||
) -> Line {
|
||||
tangent_segments(circle1, cw1, circle2, cw2).next().unwrap()
|
||||
) -> Result<Line, ()> {
|
||||
Ok(tangent_segments(circle1, cw1, circle2, cw2)?
|
||||
.next()
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
pub fn intersect_circles(circle1: &Circle, circle2: &Circle) -> Vec<Point> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue