From 1350a4111d698675469efe4be8417b9ee6e64e57 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:02:51 +0100 Subject: [PATCH] Arc optimization: symmety at 45degress If the segment is wider than 20 pixels, we optimize calculations due to symmetry - for smaller arcs the result looks better without optimization. As a side-effect, we have enough computing power left to go through the complete circumference, avoiding holes. --- wled00/FX_fcn.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e8a3217f..fa464320 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -889,16 +889,23 @@ void IRAM_ATTR_YN Segment::setPixelColor(int i, uint32_t col) //WLEDMM: IRAM_ATT else { //WLEDMM: drawArc(0, 0, i, col); could work as alternative - //WLEDMM: some opimizations for the drawing loop - float radius = float(i); // pre-calculate, for some speed - float step = HALF_PI / (2.85f * radius); - unsigned numSteps = 1 + ((HALF_PI + step/2.0f) / step); // pre-calculate, so the compiler can better optimize the for loop + //WLEDMM: some optimizations for the drawing loop + // pre-calculate loop limits, exploit symmetry at 45deg + float radius = float(i); + // float step = HALF_PI / (2.85f * radius); // upstream uses this + float step = HALF_PI / (M_PI * radius); // WLEDMM we use the correct circumference + bool useSymmetry = (max(vH, vW) > 20); // for segments wider than 20 pixels, we exploit symmetry + unsigned numSteps; + if (useSymmetry) numSteps = 1 + ((HALF_PI/2.0f + step/2.0f) / step); // with symmetry + else numSteps = 1 + ((HALF_PI + step/2.0f) / step); // without symmetry + float rad = 0.0f; for (unsigned count = 0; count < numSteps; count++) { // may want to try float version as well (with or without antialiasing) int x = roundf(sinf(rad) * radius); int y = roundf(cosf(rad) * radius); setPixelColorXY(x, y, col); + if(useSymmetry) setPixelColorXY(y, x, col);// WLEDMM rad += step; }