From 8c4879f15d6d1c699aac7d3f395b6366280e222d Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Mon, 6 May 2024 22:43:18 +0200 Subject: [PATCH] common: fix a precision issue in appendArc api For angles close to multiples of pi/2, precision based on FLT_EPSILON was insufficient. It either led to the creation of an additional cubic segment filled with erroneous values or NaNs, or it resulted in the drawing of an angle for a sweep close to 0. --- src/renderer/tvgShape.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/renderer/tvgShape.cpp b/src/renderer/tvgShape.cpp index da1fc7f0..a6d09d92 100644 --- a/src/renderer/tvgShape.cpp +++ b/src/renderer/tvgShape.cpp @@ -145,13 +145,15 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa //just circle if (sweep >= 360.0f || sweep <= -360.0f) return appendCircle(cx, cy, radius, radius); + const float arcPrecision = 1e-5f; startAngle = mathDeg2Rad(startAngle); sweep = mathDeg2Rad(sweep); - auto nCurves = ceil(fabsf(sweep / MATH_PI2)); + auto nCurves = static_cast(fabsf(sweep / MATH_PI2)); + if (fabsf(sweep / MATH_PI2) - nCurves > arcPrecision) ++nCurves; auto sweepSign = (sweep < 0 ? -1 : 1); auto fract = fmodf(sweep, MATH_PI2); - fract = (mathZero(fract)) ? MATH_PI2 * sweepSign : fract; + fract = (fabsf(fract) < arcPrecision) ? MATH_PI2 * sweepSign : fract; //Start from here Point start = {radius * cosf(startAngle), radius * sinf(startAngle)};