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<(), ()> {
|
fn finish_in_dot(&mut self, head: Head, into: DotIndex, width: f64) -> Result<(), ()> {
|
||||||
let tangent = self
|
let tangent = self
|
||||||
.guide(&Default::default())
|
.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 head = self.extend_head(head, tangent.start_point())?;
|
||||||
|
|
||||||
let net = self.layout.primitive(head.dot()).weight().net;
|
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 to_cw = self.guide(&Default::default()).head_cw(&to_head).unwrap();
|
||||||
let tangent = self
|
let tangent = self
|
||||||
.guide(&Default::default())
|
.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 head = self.extend_head(head, tangent.start_point())?;
|
||||||
let _to_head = self.extend_head(to_head, tangent.end_point())?;
|
let _to_head = self.extend_head(to_head, tangent.end_point())?;
|
||||||
|
|
@ -119,7 +119,7 @@ impl<'a> Draw<'a> {
|
||||||
) -> Result<SegbendHead, ()> {
|
) -> Result<SegbendHead, ()> {
|
||||||
let mut tangents = self
|
let mut tangents = self
|
||||||
.guide(&Default::default())
|
.guide(&Default::default())
|
||||||
.head_around_dot_segments(&head, around, width);
|
.head_around_dot_segments(&head, around, width)?;
|
||||||
let mut dirs = [true, false];
|
let mut dirs = [true, false];
|
||||||
|
|
||||||
if tangents.1.euclidean_length() < tangents.0.euclidean_length() {
|
if tangents.1.euclidean_length() < tangents.0.euclidean_length() {
|
||||||
|
|
@ -154,7 +154,7 @@ impl<'a> Draw<'a> {
|
||||||
) -> Result<SegbendHead, ()> {
|
) -> Result<SegbendHead, ()> {
|
||||||
let mut tangents = self
|
let mut tangents = self
|
||||||
.guide(&Default::default())
|
.guide(&Default::default())
|
||||||
.head_around_bend_segments(&head, around, width);
|
.head_around_bend_segments(&head, around, width)?;
|
||||||
let mut dirs = [true, false];
|
let mut dirs = [true, false];
|
||||||
|
|
||||||
if tangents.1.euclidean_length() < tangents.0.euclidean_length() {
|
if tangents.1.euclidean_length() < tangents.0.euclidean_length() {
|
||||||
|
|
@ -206,7 +206,7 @@ impl<'a> Draw<'a> {
|
||||||
|
|
||||||
let alternate_tangent = self
|
let alternate_tangent = self
|
||||||
.guide(&Default::default())
|
.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;
|
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 from_circle = self.head_circle(head, width);
|
||||||
let to_circle = Circle {
|
let to_circle = Circle {
|
||||||
pos: self.layout.primitive(into).weight().circle.pos,
|
pos: self.layout.primitive(into).weight().circle.pos,
|
||||||
|
|
@ -39,14 +44,14 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
head: &Head,
|
head: &Head,
|
||||||
around: DotIndex,
|
around: DotIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> (Line, Line) {
|
) -> Result<(Line, Line), ()> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.dot_circle(around, width);
|
let to_circle = self.dot_circle(around, width);
|
||||||
|
|
||||||
let from_cw = self.head_cw(head);
|
let from_cw = self.head_cw(head);
|
||||||
let tangents: Vec<Line> =
|
let tangents: Vec<Line> =
|
||||||
math::tangent_segments(from_circle, from_cw, to_circle, None).collect();
|
math::tangent_segments(from_circle, from_cw, to_circle, None)?.collect();
|
||||||
(tangents[0], tangents[1])
|
Ok((tangents[0], tangents[1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn head_around_dot_segment(
|
pub fn head_around_dot_segment(
|
||||||
|
|
@ -55,7 +60,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
around: DotIndex,
|
around: DotIndex,
|
||||||
cw: bool,
|
cw: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Line {
|
) -> Result<Line, ()> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.dot_circle(around, width);
|
let to_circle = self.dot_circle(around, width);
|
||||||
|
|
||||||
|
|
@ -68,14 +73,14 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
head: &Head,
|
head: &Head,
|
||||||
around: BendIndex,
|
around: BendIndex,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> (Line, Line) {
|
) -> Result<(Line, Line), ()> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.bend_circle(around, width);
|
let to_circle = self.bend_circle(around, width);
|
||||||
|
|
||||||
let from_cw = self.head_cw(head);
|
let from_cw = self.head_cw(head);
|
||||||
let tangents: Vec<Line> =
|
let tangents: Vec<Line> =
|
||||||
math::tangent_segments(from_circle, from_cw, to_circle, None).collect();
|
math::tangent_segments(from_circle, from_cw, to_circle, None)?.collect();
|
||||||
(tangents[0], tangents[1])
|
Ok((tangents[0], tangents[1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn head_around_bend_segment(
|
pub fn head_around_bend_segment(
|
||||||
|
|
@ -84,7 +89,7 @@ impl<'a, 'b> Guide<'a, 'b> {
|
||||||
around: BendIndex,
|
around: BendIndex,
|
||||||
cw: bool,
|
cw: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
) -> Line {
|
) -> Result<Line, ()> {
|
||||||
let from_circle = self.head_circle(head, width);
|
let from_circle = self.head_circle(head, width);
|
||||||
let to_circle = self.bend_circle(around, 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 epsilon = 1e-9;
|
||||||
let dr = r2 - r1;
|
let dr = r2 - r1;
|
||||||
let norm = center.x() * center.x() + center.y() * center.y();
|
let norm = center.x() * center.x() + center.y() * center.y();
|
||||||
let discriminant = norm - dr * dr;
|
let discriminant = norm - dr * dr;
|
||||||
|
|
||||||
if discriminant < -epsilon {
|
if discriminant < -epsilon {
|
||||||
panic!();
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let sqrt_discriminant = f64::sqrt(f64::abs(discriminant));
|
let sqrt_discriminant = f64::sqrt(f64::abs(discriminant));
|
||||||
|
|
||||||
CanonicalLine {
|
Ok(CanonicalLine {
|
||||||
a: (center.x() * dr + center.y() * sqrt_discriminant) / norm,
|
a: (center.x() * dr + center.y() * sqrt_discriminant) / norm,
|
||||||
b: (center.y() * dr - center.x() * sqrt_discriminant) / norm,
|
b: (center.y() * dr - center.x() * sqrt_discriminant) / norm,
|
||||||
c: r1,
|
c: r1,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _tangents(circle1: Circle, circle2: Circle) -> [CanonicalLine; 4] {
|
fn _tangents(circle1: Circle, circle2: Circle) -> Result<[CanonicalLine; 4], ()> {
|
||||||
let mut tgs: [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() {
|
for tg in tgs.iter_mut() {
|
||||||
tg.c -= tg.a * circle1.pos.x() + tg.b * circle1.pos.y();
|
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 {
|
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();
|
.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tangent_point_pairs(circle1: Circle, circle2: Circle) -> [(Point, Point); 4] {
|
fn tangent_point_pairs(circle1: Circle, circle2: Circle) -> Result<[(Point, Point); 4], ()> {
|
||||||
let tgs = _tangents(circle1, circle2);
|
let tgs = _tangents(circle1, circle2)?;
|
||||||
|
|
||||||
[
|
Ok([
|
||||||
(
|
(
|
||||||
cast_point_to_canonical_line(circle1.pos, tgs[0]),
|
cast_point_to_canonical_line(circle1.pos, tgs[0]),
|
||||||
cast_point_to_canonical_line(circle2.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(circle1.pos, tgs[3]),
|
||||||
cast_point_to_canonical_line(circle2.pos, tgs[3]),
|
cast_point_to_canonical_line(circle2.pos, tgs[3]),
|
||||||
),
|
),
|
||||||
]
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tangent_segments(
|
pub fn tangent_segments(
|
||||||
|
|
@ -97,8 +97,8 @@ pub fn tangent_segments(
|
||||||
cw1: Option<bool>,
|
cw1: Option<bool>,
|
||||||
circle2: Circle,
|
circle2: Circle,
|
||||||
cw2: Option<bool>,
|
cw2: Option<bool>,
|
||||||
) -> impl Iterator<Item = Line> {
|
) -> Result<impl Iterator<Item = Line>, ()> {
|
||||||
tangent_point_pairs(circle1, circle2)
|
Ok(tangent_point_pairs(circle1, circle2)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |tangent_point_pair| {
|
.filter_map(move |tangent_point_pair| {
|
||||||
if let Some(cw1) = cw1 {
|
if let Some(cw1) = cw1 {
|
||||||
|
|
@ -120,7 +120,7 @@ pub fn tangent_segments(
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Line::new(tangent_point_pair.0, tangent_point_pair.1))
|
Some(Line::new(tangent_point_pair.0, tangent_point_pair.1))
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tangent_segment(
|
pub fn tangent_segment(
|
||||||
|
|
@ -128,8 +128,10 @@ pub fn tangent_segment(
|
||||||
cw1: Option<bool>,
|
cw1: Option<bool>,
|
||||||
circle2: Circle,
|
circle2: Circle,
|
||||||
cw2: Option<bool>,
|
cw2: Option<bool>,
|
||||||
) -> Line {
|
) -> Result<Line, ()> {
|
||||||
tangent_segments(circle1, cw1, circle2, cw2).next().unwrap()
|
Ok(tangent_segments(circle1, cw1, circle2, cw2)?
|
||||||
|
.next()
|
||||||
|
.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intersect_circles(circle1: &Circle, circle2: &Circle) -> Vec<Point> {
|
pub fn intersect_circles(circle1: &Circle, circle2: &Circle) -> Vec<Point> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue