The issue I am having is that while plotting polygons out of bounds, I get the following error:
thread 'main' panicked at 'attempt to subtract with overflow', .../plotters/plotters-backend/src/rasterizer/polygon.rs:98:54
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I have looked a bit into the issue, and while the error happens in polygon.rs:98:54, the actual problem is in the path.rs:38.
What seems to be happening is that as the polygon goes out of bounds, it is clipped to stay within the axes.
This clipping introduces a lot of colinear points. The check for colinearity does not seem to catch all these cases.
If we the example listed in the reproduction section and look what compute_polygon_vertex does with the first three points:
The variables until line 38
let triple = [ // First three points clipped to the area and translated to backend coords
[92, 728],
[40, 728],
[315, 728],
];
// Tangent and normal vector between triple[0] and triple[1]
let a_t = (-1, 0);
let a_n = (-0, -1);
// Tangent and normal vector between triple[1] and triple[2]
let b_t = (-1, 0);
let b_n = (0, 1);
Multiplying triple[1] with a_n and b_n yields different points and therefore passes the colinearity test on line 38.
But, on line 68, x and y are not updated and therefore stay at INTY.
To Reproduce
You can reproduce it using this example:
use plotters::prelude::*;
const OUT_FILE_NAME: &'static str = "plotters-doc-data/sample.png";
fn main() -> Result<(), Box<dyn std::error::Error>> {
let root_area = BitMapBackend::new(OUT_FILE_NAME, (1024, 768)).into_drawing_area();
root_area.fill(&WHITE)?;
let mut cc = ChartBuilder::on(&root_area)
.build_cartesian_2d(-10.0f64..10.0, -10.0f64..10.0)?;
let pts = [
(-8.9312, -20.0187),
(-10.1495, -22.5886),
(-11.1510, -24.7366),
(-4.3868, -12.9378),
(9.4977, 14.7489)
];
cc.draw_series(LineSeries::new(pts, RED.stroke_width(2)))
.unwrap();
// To avoid the IO failure being ignored silently, we manually call the present function
root_area.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir");
println!("Result has been saved to {}", OUT_FILE_NAME);
Ok(())
}
#[test]
fn entry_point() {
main().unwrap()
}
Possible fix
See the pull request below.
Changing the colinearity test to the following fixes the issue. It compares the delta x / delta y for both the a and b vectors.
// Check if 3 points are colinear. If so, just emit the point.
if a_t.1 * b_t.0 == a_t.0 * b_t.1 {
buf.push((b_p.0 as i32, b_p.1 as i32));
return;
}
Version Information
I was able to reproduce it on 0.3.2 and on the current master branch.
Describe the bug
The issue I am having is that while plotting polygons out of bounds, I get the following error:
I have looked a bit into the issue, and while the error happens in polygon.rs:98:54, the actual problem is in the path.rs:38.
What seems to be happening is that as the polygon goes out of bounds, it is clipped to stay within the axes. This clipping introduces a lot of colinear points. The check for colinearity does not seem to catch all these cases.
If we the example listed in the reproduction section and look what
compute_polygon_vertex
does with the first three points:The variables until line 38
Multiplying
triple[1]
witha_n
andb_n
yields different points and therefore passes the colinearity test on line 38. But, on line 68,x
andy
are not updated and therefore stay at INTY.To Reproduce You can reproduce it using this example:
Possible fix See the pull request below.
Changing the colinearity test to the following fixes the issue. It compares the delta x / delta y for both the a and b vectors.
Version Information I was able to reproduce it on 0.3.2 and on the current master branch.
Thanks in advance