diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-05-14 16:03:40 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-05-14 16:09:29 +0100 |
commit | f7d937670c22db79e597cade89e84c840b58e25e (patch) | |
tree | 6f29af520f36b9150a0526793d74bf79132b9e14 /src/cairo-arc.c | |
parent | 6867383017fcea0b1d5a4671b32382037ba9be3f (diff) | |
download | cairo-f7d937670c22db79e597cade89e84c840b58e25e.tar.gz |
arc: Use user endpoint for final step
Eliminate numerical inaccuracy from accumulating angle through
the floating point step value by using the exact end-value for the last
arc segment.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-arc.c')
-rw-r--r-- | src/cairo-arc.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/src/cairo-arc.c b/src/cairo-arc.c index 4113ef95c..5cbd11238 100644 --- a/src/cairo-arc.c +++ b/src/cairo-arc.c @@ -217,27 +217,32 @@ _cairo_arc_in_direction (cairo_t *cr, } else if (angle_max != angle_min) { cairo_matrix_t ctm; int i, segments; - double angle, angle_step; + double step; cairo_get_matrix (cr, &ctm); segments = _arc_segments_needed (angle_max - angle_min, radius, &ctm, cairo_get_tolerance (cr)); - angle_step = (angle_max - angle_min) / (double) segments; + step = (angle_max - angle_min) / segments; + segments -= 1; - if (dir == CAIRO_DIRECTION_FORWARD) { - angle = angle_min; - } else { - angle = angle_max; - angle_step = - angle_step; + if (dir == CAIRO_DIRECTION_REVERSE) { + double t; + + t = angle_min; + angle_min = angle_max; + angle_max = t; + + step = -step; } - for (i = 0; i < segments; i++, angle += angle_step) { - _cairo_arc_segment (cr, xc, yc, - radius, - angle, - angle + angle_step); + for (i = 0; i < segments; i++, angle_min += step) { + _cairo_arc_segment (cr, xc, yc, radius, + angle_min, angle_min + step); } + + _cairo_arc_segment (cr, xc, yc, radius, + angle_min, angle_max); } else { cairo_line_to (cr, xc + radius * cos (angle_min), |