Skip to content

Commit e9a8103

Browse files
committed
Fix bug 358
Numeric keypoints algorithm may loop infintately, caused by the rounding algorithm.
1 parent 082ad58 commit e9a8103

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

plotters/plotters-doc-data

plotters/src/coord/ranged1d/types/numeric.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ macro_rules! gen_key_points_comp {
118118
}
119119

120120
let mut scale = (10f64).powf((range.1 - range.0).log(10.0).floor());
121-
let mut digits = -(range.1 - range.0).log(10.0).floor() as i32 + 1;
121+
// The value granularity controls how we round the values.
122+
let mut value_granularity = scale / 10.0;
122123
fn rem_euclid(a: f64, b: f64) -> f64 {
123124
if b > 0.0 {
124125
a - (a / b).floor() * b
@@ -131,6 +132,7 @@ macro_rules! gen_key_points_comp {
131132
// The scale must yield number of points than requested
132133
if 1 + ((range.1 - range.0) / scale).floor() as usize > max_points {
133134
scale *= 10.0;
135+
value_granularity *= 10.0;
134136
}
135137

136138
'outer: loop {
@@ -148,21 +150,16 @@ macro_rules! gen_key_points_comp {
148150
scale = old_scale / nxt;
149151
}
150152
scale = old_scale / 10.0;
151-
if scale < 1.0 {
152-
digits += 1;
153-
}
153+
value_granularity /= 10.0;
154154
}
155155

156156
let mut ret = vec![];
157157
let mut left = range.0 + scale - rem_euclid(range.0, scale);
158158
let right = range.1 - rem_euclid(range.1, scale);
159159
while left <= right {
160-
let size = (10f64).powf(digits as f64 + 1.0);
161-
let new_left = (left * size).abs() + 1e-3;
162-
if left < 0.0 {
163-
left = -new_left.round() / size;
164-
} else {
165-
left = new_left.round() / size;
160+
let new_left = (left / value_granularity).round() * value_granularity;
161+
if new_left < range.0 {
162+
left = new_left + value_granularity;
166163
}
167164
ret.push(left as $type);
168165
left += scale;
@@ -384,4 +381,11 @@ mod test {
384381
let coord: RangedCoordf32 = (10.0..0.0).into();
385382
let _points = coord.key_points(10);
386383
}
384+
385+
#[test]
386+
fn regession_test_issue_358_key_points_no_hang() {
387+
let coord: RangedCoordf64 = (-200.0..801.0).into();
388+
let points = coord.key_points(500);
389+
assert!(points.len() <= 500);
390+
}
387391
}

0 commit comments

Comments
 (0)