Skip to content

Commit 01cc98f

Browse files
authored
Merge pull request #574 from el-hult/fix-562
Fix bug where close-to-collinear line segments with thickness >= 2 got size `f64::INFINITTY as i32` as coordinates.
2 parents 0af06d3 + 9557c60 commit 01cc98f

File tree

1 file changed

+34
-12
lines changed
  • plotters-backend/src/rasterizer

1 file changed

+34
-12
lines changed

plotters-backend/src/rasterizer/path.rs

+34-12
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ fn compute_polygon_vertex(triple: &[BackendCoord; 3], d: f64, buf: &mut Vec<Back
3434
f64::from(triple[1].1) + d * b_n.1,
3535
);
3636

37-
// Check if 3 points are colinear. If so, just emit the point.
38-
if a_t.1 * b_t.0 == a_t.0 * b_t.1 {
37+
// Check if 3 points are colinear, up to precision. If so, just emit the point.
38+
if (a_t.1 * b_t.0 - a_t.0 * b_t.1).abs() <= f64::EPSILON {
3939
buf.push((a_p.0 as i32, a_p.1 as i32));
4040
return;
4141
}
@@ -61,16 +61,10 @@ fn compute_polygon_vertex(triple: &[BackendCoord; 3], d: f64, buf: &mut Vec<Back
6161
let b1 = -b_t.1;
6262
let c1 = b_p.1 - a_p.1;
6363

64-
let mut x = f64::INFINITY;
65-
let mut y = f64::INFINITY;
66-
67-
// Well if the determinant is not 0, then we can actually get a intersection point.
68-
if (a0 * b1 - a1 * b0).abs() > f64::EPSILON {
69-
let u = (c0 * b1 - c1 * b0) / (a0 * b1 - a1 * b0);
70-
71-
x = a_p.0 + u * a_t.0;
72-
y = a_p.1 + u * a_t.1;
73-
}
64+
// Since the points are not collinear, the determinant is not 0, and we can get a intersection point.
65+
let u = (c0 * b1 - c1 * b0) / (a0 * b1 - a1 * b0);
66+
let x = a_p.0 + u * a_t.0;
67+
let y = a_p.1 + u * a_t.1;
7468

7569
let cross_product = a_t.0 * b_t.1 - a_t.1 * b_t.0;
7670
if (cross_product < 0.0 && d < 0.0) || (cross_product > 0.0 && d > 0.0) {
@@ -149,3 +143,31 @@ pub fn polygonize(vertices: &[BackendCoord], stroke_width: u32) -> Vec<BackendCo
149143

150144
ret
151145
}
146+
147+
#[cfg(test)]
148+
mod test
149+
{
150+
use super::*;
151+
152+
/// Test for regression with respect to https://github.com/plotters-rs/plotters/issues/562
153+
#[test]
154+
fn test_no_inf_in_compute_polygon_vertex() {
155+
let path = [(335, 386), (338, 326), (340, 286)];
156+
let mut buf = Vec::new();
157+
compute_polygon_vertex(&path, 2.0, buf.as_mut());
158+
assert!(!buf.is_empty());
159+
let nani32 = f64::INFINITY as i32;
160+
assert!(!buf.iter().any(|&v| v.0 == nani32 || v.1 == nani32));
161+
}
162+
163+
/// Correct 90 degree turn to the right
164+
#[test]
165+
fn standard_corner() {
166+
let path = [(10, 10), (20, 10), (20, 20)];
167+
let mut buf = Vec::new();
168+
compute_polygon_vertex(&path, 2.0, buf.as_mut());
169+
assert!(!buf.is_empty());
170+
let buf2 = vec![(18, 12)];
171+
assert_eq!(buf,buf2);
172+
}
173+
}

0 commit comments

Comments
 (0)