@@ -743,18 +743,21 @@ void WLED_O2_ATTR Segment::setPixelColor(int i, uint32_t col) const
743743 else for (int x = 0 ; x < vW; x++) setPixelColorRaw (XY (x, vH - i - 1 ), col);
744744 break ;
745745 case M12_pArc: {
746- // expand in circular fashion from center
747- if (i == 0 ) setPixelColorXY (0 , 0 , col);
748- else if (i == 2 ) setPixelColorXY (1 , 1 , col);
746+ // expand in circular fashion from top left corner
747+ // Tony Barrera's circle algorithm
748+ // https://softwareengineering.stackexchange.com/questions/287478/drawing-concentric-circles-without-gaps/357445#357445
749+
750+ if (i == 0 ) setPixelColorXYRaw (0 , 0 , col); // 0 and 2 special cases to prevent square
751+ else if (i == 2 ) setPixelColorXYRaw (1 , 1 , col);
752+ else if (i == vLength ()-1 ) setPixelColorXYRaw (vW-1 , vH-1 , col); // last i always draws bottom right corner
749753
750754 int x = 0 , y = i; // i is the radius
751755 int d = -(i >> 1 ); // Initial decision parameter
752756
753- // Barrera's circle algorithm
754757 while (x <= y) {
755- if (!(i == x && i == y) ) { // prevent early square
756- setPixelColorXY (x, y, col);
757- setPixelColorXY (y, x, col);
758+ if (i != x || i != y ) { // prevent early square
759+ if (y < vH && x < vW) setPixelColorXYRaw (x, y, col);
760+ if (y < vW && x < vH) setPixelColorXYRaw (y, x, col);
758761 }
759762 if (d <= 0 ) d += ++x;
760763 else d -= --y;
@@ -937,6 +940,7 @@ uint32_t WLED_O2_ATTR Segment::getPixelColor(int i) const
937940 break ;
938941 case M12_pArc:
939942 if (i >= vW && i >= vH) { // Barrera's circle algorithm
943+ x = vW - 1 ; y = vH - 1 ; // default to bottom right if not found
940944 int x2 = 0 , y2 = i, d = -(i >> 1 );
941945 int validCount = 0 ; // return 2nd non mirrored pixel if available
942946 while (x2 <= y2 && validCount < 2 ) {
0 commit comments