From da79b93387cb80873d5dc65cd864be866a4b70bf Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Tue, 7 May 2024 18:04:29 -0400
Subject: [PATCH 01/15] Added Pinwheel Expand 1D Effect
---
wled00/FX.h | 3 ++-
wled00/FX_fcn.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++-
wled00/data/index.js | 1 +
3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/wled00/FX.h b/wled00/FX.h
index 106a6712c..b1e6823ff 100644
--- a/wled00/FX.h
+++ b/wled00/FX.h
@@ -320,7 +320,8 @@ typedef enum mapping1D2D {
M12_Pixels = 0,
M12_pBar = 1,
M12_pArc = 2,
- M12_pCorner = 3
+ M12_pCorner = 3,
+ M12_sPinwheel = 4
} mapping1D2D_t;
// segment, 80 bytes
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index ce510f16e..7f8c1319a 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -637,6 +637,14 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
return vLen;
}
+// Constants for mapping mode "Pinwheel"
+constexpr int Pinwheel_Steps_Medium = 208; // no holes up to 32x32; 60fps
+constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
+constexpr int Pinwheel_Steps_Big = 360; // no holes expected up to 58x58; 40fps
+constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
+constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...360 to Radians
+
+
// 1D strip
uint16_t IRAM_ATTR Segment::virtualLength() const {
#ifndef WLED_DISABLE_2D
@@ -652,6 +660,12 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
case M12_pArc:
vLen = max(vW,vH); // get the longest dimension
break;
+ case M12_sPinwheel:
+ if (max(vW,vH) <= Pinwheel_Size_Medium)
+ vLen = Pinwheel_Steps_Medium;
+ else
+ vLen = Pinwheel_Steps_Big;
+ break;
}
return vLen;
}
@@ -718,6 +732,38 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
for (int x = 0; x <= i; x++) setPixelColorXY(x, i, col);
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
break;
+ case M12_sPinwheel: {
+ // i = angle --> 0 through 359 (Big), OR 0 through 208 (Medium)
+ float centerX = roundf((vW-1) / 2.0f);
+ float centerY = roundf((vH-1) / 2.0f);
+ // int maxDistance = sqrt(centerX * centerX + centerY * centerY) + 1;
+ float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
+ float cosVal = cosf(angleRad);
+ float sinVal = sinf(angleRad);
+
+ // draw line at angle, starting at center and ending at the segment edge
+ // we use fixed point math for better speed. Starting distance is 0.5 for better rounding
+ constexpr int_fast32_t Fixed_Scale = 512; // fixpoint scaling factor
+ int_fast32_t posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point
+ int_fast32_t posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point
+ int_fast16_t inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point)
+ int_fast16_t inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point)
+
+ int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
+ int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
+ // draw until we hit any edge
+ while ((posx > 0) && (posy > 0) && (posx < maxX) && (posy < maxY)) {
+ // scale down to integer (compiler will replace division with appropriate bitshift)
+ int x = posx / Fixed_Scale;
+ int y = posy / Fixed_Scale;
+ // set pixel
+ setPixelColorXY(x, y, col);
+ // advance to next position
+ posx += inc_x;
+ posy += inc_y;
+ }
+ break;
+ }
}
return;
} else if (Segment::maxHeight!=1 && (width()==1 || height()==1)) {
@@ -833,7 +879,17 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
// use longest dimension
return vW>vH ? getPixelColorXY(i, 0) : getPixelColorXY(0, i);
break;
- }
+ case M12_sPinwheel:
+ // not 100% accurate, returns outer edge of circle
+ float distance = max(1.0f, min(vH-1, vW-1) / 2.0f);
+ float centerX = (vW - 1) / 2.0f;
+ float centerY = (vH - 1) / 2.0f;
+ float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
+ int x = roundf(centerX + distance * cosf(angleRad));
+ int y = roundf(centerY + distance * sinf(angleRad));
+ return getPixelColorXY(x, y);
+ break;
+ }
return 0;
}
#endif
diff --git a/wled00/data/index.js b/wled00/data/index.js
index d33fb63f7..26d78b284 100644
--- a/wled00/data/index.js
+++ b/wled00/data/index.js
@@ -801,6 +801,7 @@ function populateSegments(s)
``+
``+
``+
+ ``+
``+
``;
let sndSim = `
Sound sim
`+
From 6a18ce078e3b2f31404d3309b39985638d53fcf4 Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Thu, 9 May 2024 20:38:41 -0400
Subject: [PATCH 02/15] Pinwheel Expand1D changes
cosf/sinf changed to cos_t/sin_t. int_fast32_t and int_fast_16_t changed to int.
---
wled00/FX_fcn.cpp | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 7f8c1319a..88ec78f3e 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -738,16 +738,17 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
float centerY = roundf((vH-1) / 2.0f);
// int maxDistance = sqrt(centerX * centerX + centerY * centerY) + 1;
float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
- float cosVal = cosf(angleRad);
- float sinVal = sinf(angleRad);
+ float cosVal = cos_t(angleRad);
+ float sinVal = sin_t(angleRad);
// draw line at angle, starting at center and ending at the segment edge
// we use fixed point math for better speed. Starting distance is 0.5 for better rounding
- constexpr int_fast32_t Fixed_Scale = 512; // fixpoint scaling factor
- int_fast32_t posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point
- int_fast32_t posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point
- int_fast16_t inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point)
- int_fast16_t inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point)
+ // int_fast16_t and int_fast32_t types changed to int, minimum bits commented
+ constexpr int Fixed_Scale = 512; // fixpoint scaling factor 18 bit
+ int posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point 18 bit
+ int posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point 18 bit
+ int inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point) 10 bit
+ int inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point) 10 bit
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
@@ -885,8 +886,8 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
float centerX = (vW - 1) / 2.0f;
float centerY = (vH - 1) / 2.0f;
float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
- int x = roundf(centerX + distance * cosf(angleRad));
- int y = roundf(centerY + distance * sinf(angleRad));
+ int x = roundf(centerX + distance * cos_t(angleRad));
+ int y = roundf(centerY + distance * sin_t(angleRad));
return getPixelColorXY(x, y);
break;
}
From d3492b5b6c38e6a8cb2136bc8d7654a4594b59df Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Fri, 10 May 2024 16:06:37 -0400
Subject: [PATCH 03/15] Pinwheel Expand 1D Bug Fix
Removed holes on 31x31 and 32x32 grids.
---
wled00/FX_fcn.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 88ec78f3e..17a504ea0 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -639,7 +639,7 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
// Constants for mapping mode "Pinwheel"
constexpr int Pinwheel_Steps_Medium = 208; // no holes up to 32x32; 60fps
-constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
+constexpr int Pinwheel_Size_Medium = 30; // larger than this -> use "Big"
constexpr int Pinwheel_Steps_Big = 360; // no holes expected up to 58x58; 40fps
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...360 to Radians
From 9e468bd059510c66bbb99e41ed4855193a9cc05c Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Sat, 11 May 2024 13:57:21 -0400
Subject: [PATCH 04/15] Pinwheel Expand 1D Optimizations
Added small pinwheel size. Adjusts medium and large values.
---
wled00/FX_fcn.cpp | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 17a504ea0..ec0e087bc 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -638,9 +638,12 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
}
// Constants for mapping mode "Pinwheel"
-constexpr int Pinwheel_Steps_Medium = 208; // no holes up to 32x32; 60fps
-constexpr int Pinwheel_Size_Medium = 30; // larger than this -> use "Big"
-constexpr int Pinwheel_Steps_Big = 360; // no holes expected up to 58x58; 40fps
+constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16;
+constexpr int Pinwheel_Size_Small = 16;
+constexpr int Pinwheel_Steps_Medium = 200; // no holes up to 32x32; 60fps
+constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
+constexpr int Pinwheel_Steps_Big = 296; // no holes expected up to 58x58; 40fps
+constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...208 to Radians
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...360 to Radians
@@ -661,7 +664,9 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
vLen = max(vW,vH); // get the longest dimension
break;
case M12_sPinwheel:
- if (max(vW,vH) <= Pinwheel_Size_Medium)
+ if (max(vW,vH) <= Pinwheel_Size_Small)
+ vLen = Pinwheel_Steps_Small;
+ else if (max(vW,vH) <= Pinwheel_Size_Medium)
vLen = Pinwheel_Steps_Medium;
else
vLen = Pinwheel_Steps_Big;
@@ -736,8 +741,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
// i = angle --> 0 through 359 (Big), OR 0 through 208 (Medium)
float centerX = roundf((vW-1) / 2.0f);
float centerY = roundf((vH-1) / 2.0f);
- // int maxDistance = sqrt(centerX * centerX + centerY * centerY) + 1;
- float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
+ float angleRad = (max(vW, vH) > Pinwheel_Size_Small ? (max(vW, vH) > Pinwheel_Size_Medium ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small); // angle in radians
float cosVal = cos_t(angleRad);
float sinVal = sin_t(angleRad);
@@ -885,7 +889,7 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
float distance = max(1.0f, min(vH-1, vW-1) / 2.0f);
float centerX = (vW - 1) / 2.0f;
float centerY = (vH - 1) / 2.0f;
- float angleRad = (max(vW,vH) > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med; // angle in radians
+ float angleRad = (max(vW, vH) > Pinwheel_Size_Small ? (max(vW, vH) > Pinwheel_Size_Medium ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small); // angle in radians
int x = roundf(centerX + distance * cos_t(angleRad));
int y = roundf(centerY + distance * sin_t(angleRad));
return getPixelColorXY(x, y);
From 3078bea7cce95038bc354acd73caecf9ca7327d7 Mon Sep 17 00:00:00 2001
From: Frank
Date: Sun, 12 May 2024 13:29:04 +0200
Subject: [PATCH 05/15] Pinwheel optimization: do nor repaint "same" pixels in
a line
avoids back to back duplicates within the same line
---
wled00/FX_fcn.cpp | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index ec0e087bc..b06b0dceb 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -745,10 +745,13 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
float cosVal = cos_t(angleRad);
float sinVal = sin_t(angleRad);
+ // avoid re-painting the same pixel
+ int lastX = INT_MIN; // impossible position
+ int lastY = INT_MIN; // impossible position
// draw line at angle, starting at center and ending at the segment edge
// we use fixed point math for better speed. Starting distance is 0.5 for better rounding
// int_fast16_t and int_fast32_t types changed to int, minimum bits commented
- constexpr int Fixed_Scale = 512; // fixpoint scaling factor 18 bit
+ constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
int posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point 18 bit
int posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point 18 bit
int inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point) 10 bit
@@ -756,13 +759,20 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
- // draw until we hit any edge
+ // draw ray until we hit any edge
while ((posx > 0) && (posy > 0) && (posx < maxX) && (posy < maxY)) {
// scale down to integer (compiler will replace division with appropriate bitshift)
int x = posx / Fixed_Scale;
int y = posy / Fixed_Scale;
+#if 1
// set pixel
- setPixelColorXY(x, y, col);
+ if (x != lastX || y != lastY) setPixelColorXY(x, y, col); // only paint if pixel position is different
+#else
+ // experimental: only set pixel if color is different (trade getPC performance against setPC)
+ if ((x != lastX || y != lastY) && (getPixelColorXY(x, y) != col)) setPixelColorXY(x, y, col); // only paint if pixel color is different
+#endif
+ lastX = x;
+ lastY = y;
// advance to next position
posx += inc_x;
posy += inc_y;
From c84d4c637d46fadfa09855fe68465f8db780f68a Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Sun, 12 May 2024 11:52:31 -0400
Subject: [PATCH 06/15] Pinwheel Expand 1D Optimization
Changed method for drawing odd numbered rays.
---
wled00/FX_fcn.cpp | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index b06b0dceb..26ae9ca11 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -640,13 +640,13 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
// Constants for mapping mode "Pinwheel"
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16;
constexpr int Pinwheel_Size_Small = 16;
-constexpr int Pinwheel_Steps_Medium = 200; // no holes up to 32x32; 60fps
+constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32; 60fps
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
constexpr int Pinwheel_Steps_Big = 296; // no holes expected up to 58x58; 40fps
constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...208 to Radians
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...360 to Radians
-
+int prevRay = INT_MIN;
// 1D strip
uint16_t IRAM_ATTR Segment::virtualLength() const {
@@ -738,7 +738,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
break;
case M12_sPinwheel: {
- // i = angle --> 0 through 359 (Big), OR 0 through 208 (Medium)
+ // i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
float centerX = roundf((vW-1) / 2.0f);
float centerY = roundf((vH-1) / 2.0f);
float angleRad = (max(vW, vH) > Pinwheel_Size_Small ? (max(vW, vH) > Pinwheel_Size_Medium ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small); // angle in radians
@@ -759,6 +759,14 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
+
+ // Odd rays start further from center if prevRay started at center.
+ if (i % 2 == 1 && (i - 1 == prevRay || i + 1 == prevRay)) {
+ posx = (posx + inc_x * (vW/4));
+ posy = (posy + inc_y * (vH/4));
+ }
+ prevRay = i;
+
// draw ray until we hit any edge
while ((posx > 0) && (posy > 0) && (posx < maxX) && (posy < maxY)) {
// scale down to integer (compiler will replace division with appropriate bitshift)
From f26bb26ffad857e49b812843f006bfa5f74947be Mon Sep 17 00:00:00 2001
From: Frank
Date: Sun, 12 May 2024 22:35:33 +0200
Subject: [PATCH 07/15] Update FX_fcn.cpp
* minor cleanup, moved prevRay into setPixelColor
* removed experimental code (too slow)
* comments cleanup
---
wled00/FX_fcn.cpp | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 26ae9ca11..ca1527a7c 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -638,15 +638,14 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
}
// Constants for mapping mode "Pinwheel"
-constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16;
+constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
constexpr int Pinwheel_Size_Small = 16;
-constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32; 60fps
+constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
-constexpr int Pinwheel_Steps_Big = 296; // no holes expected up to 58x58; 40fps
-constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...208 to Radians
-constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
-constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...360 to Radians
-int prevRay = INT_MIN;
+constexpr int Pinwheel_Steps_Big = 296; // no holes expected up to 56x56
+constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...72 to Radians
+constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
+constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...296 to Radians
// 1D strip
uint16_t IRAM_ATTR Segment::virtualLength() const {
@@ -738,6 +737,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
break;
case M12_sPinwheel: {
+ static int prevRay = INT_MIN; // previous ray number
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
float centerX = roundf((vW-1) / 2.0f);
float centerY = roundf((vH-1) / 2.0f);
@@ -761,9 +761,9 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
// Odd rays start further from center if prevRay started at center.
- if (i % 2 == 1 && (i - 1 == prevRay || i + 1 == prevRay)) {
- posx = (posx + inc_x * (vW/4));
- posy = (posy + inc_y * (vH/4));
+ if ((i % 2 == 1) && (i - 1 == prevRay || i + 1 == prevRay)) {
+ posx += inc_x * (vW/4);
+ posy += inc_y * (vH/4);
}
prevRay = i;
@@ -772,13 +772,8 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
// scale down to integer (compiler will replace division with appropriate bitshift)
int x = posx / Fixed_Scale;
int y = posy / Fixed_Scale;
-#if 1
// set pixel
if (x != lastX || y != lastY) setPixelColorXY(x, y, col); // only paint if pixel position is different
-#else
- // experimental: only set pixel if color is different (trade getPC performance against setPC)
- if ((x != lastX || y != lastY) && (getPixelColorXY(x, y) != col)) setPixelColorXY(x, y, col); // only paint if pixel color is different
-#endif
lastX = x;
lastY = y;
// advance to next position
From ea83ec496b923b1d8e44bb3d5e46364abea5a65a Mon Sep 17 00:00:00 2001
From: Frank
Date: Sun, 12 May 2024 23:05:58 +0200
Subject: [PATCH 08/15] pinwheel - parameter tuning to fix some holes
fixing holes that appeared during testing
* at 52x52 (big 296 -> 304)
* at 24x32 (medium 192 -> 208)
* at 12x16 (small 72 -> 82)
... there is still one hole at 14x16 ... well wtf
---
wled00/FX_fcn.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index ca1527a7c..e29cbafa1 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -638,14 +638,14 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
}
// Constants for mapping mode "Pinwheel"
-constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
+constexpr int Pinwheel_Steps_Small = 82; // no holes up to 16x16
constexpr int Pinwheel_Size_Small = 16;
-constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32
+constexpr int Pinwheel_Steps_Medium = 208; // no holes up to 32x32
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
-constexpr int Pinwheel_Steps_Big = 296; // no holes expected up to 56x56
-constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...72 to Radians
-constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
-constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...296 to Radians
+constexpr int Pinwheel_Steps_Big = 304; // no holes expected up to 56x56
+constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...82 to Radians
+constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
+constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...304 to Radians
// 1D strip
uint16_t IRAM_ATTR Segment::virtualLength() const {
From 9e0b91ac17f4ad84978be399d7c8f066a4508b85 Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Sun, 12 May 2024 17:46:42 -0400
Subject: [PATCH 09/15] Pinwheel changes.
Jump distance for odd rays fixed. Removed holes on rectangular matrices.
---
wled00/FX_fcn.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index ca1527a7c..1dd8da69e 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -762,8 +762,9 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
// Odd rays start further from center if prevRay started at center.
if ((i % 2 == 1) && (i - 1 == prevRay || i + 1 == prevRay)) {
- posx += inc_x * (vW/4);
- posy += inc_y * (vH/4);
+ int jump = min(vW/3, vH/3);
+ posx += inc_x * jump;
+ posy += inc_y * jump;
}
prevRay = i;
From 1d7789f544540b5aa66099c2e54f4adaac09937a Mon Sep 17 00:00:00 2001
From: Frank <91616163+softhack007@users.noreply.github.com>
Date: Mon, 13 May 2024 19:27:41 +0200
Subject: [PATCH 10/15] pinwheel bugfixing
* setPixelColor: ensure that 0/0 is used
* getPixelColor: accuracy improvements
unfortunately, "scrolling" audioreactive effects are still not working properly - they end after 1/4 of the circle. Could be due to limited resolution of getPixelColor.
---
wled00/FX_fcn.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index c1ae6c2b9..c2f7cef46 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -737,7 +737,6 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
break;
case M12_sPinwheel: {
- static int prevRay = INT_MIN; // previous ray number
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
float centerX = roundf((vW-1) / 2.0f);
float centerY = roundf((vH-1) / 2.0f);
@@ -761,6 +760,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
// Odd rays start further from center if prevRay started at center.
+ static int prevRay = INT_MIN; // previous ray number
if ((i % 2 == 1) && (i - 1 == prevRay || i + 1 == prevRay)) {
int jump = min(vW/3, vH/3);
posx += inc_x * jump;
@@ -769,7 +769,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
prevRay = i;
// draw ray until we hit any edge
- while ((posx > 0) && (posy > 0) && (posx < maxX) && (posy < maxY)) {
+ while ((posx >= 0) && (posy >= 0) && (posx < maxX) && (posy < maxY)) {
// scale down to integer (compiler will replace division with appropriate bitshift)
int x = posx / Fixed_Scale;
int y = posy / Fixed_Scale;
@@ -900,12 +900,17 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
break;
case M12_sPinwheel:
// not 100% accurate, returns outer edge of circle
- float distance = max(1.0f, min(vH-1, vW-1) / 2.0f);
+ int maxXY = max(vW, vH); // max dimension
+ int minXY = min(vW, vH); // circle diameter
+ float distance = max(1.0f, 0.5f * minXY) -0.5f;
float centerX = (vW - 1) / 2.0f;
float centerY = (vH - 1) / 2.0f;
- float angleRad = (max(vW, vH) > Pinwheel_Size_Small ? (max(vW, vH) > Pinwheel_Size_Medium ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small); // angle in radians
+ float angleRad = (maxXY > Pinwheel_Size_Small) ? ((maxXY > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small; // angle in radians
int x = roundf(centerX + distance * cos_t(angleRad));
int y = roundf(centerY + distance * sin_t(angleRad));
+ // move "slightly off" coordinates back into segment
+ x = max(0, min(x, int(vW) - 1));
+ y = max(0, min(y, int(vH) - 1));
return getPixelColorXY(x, y);
break;
}
From 1d20f18d3f1e09de65ae4cc75e7dca437a9e56bf Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Mon, 13 May 2024 17:43:31 -0400
Subject: [PATCH 11/15] Pinwheel bugfix
Fixed getPixelColor.
---
wled00/FX_fcn.cpp | 47 +++++++++++++++++++++++++++++++----------------
1 file changed, 31 insertions(+), 16 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index c2f7cef46..3fd9245ea 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -638,13 +638,13 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
}
// Constants for mapping mode "Pinwheel"
-constexpr int Pinwheel_Steps_Small = 82; // no holes up to 16x16
+constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
constexpr int Pinwheel_Size_Small = 16;
-constexpr int Pinwheel_Steps_Medium = 208; // no holes up to 32x32
+constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
constexpr int Pinwheel_Steps_Big = 304; // no holes expected up to 56x56
-constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...82 to Radians
-constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...208 to Radians
+constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...72 to Radians
+constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...304 to Radians
// 1D strip
@@ -762,7 +762,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
// Odd rays start further from center if prevRay started at center.
static int prevRay = INT_MIN; // previous ray number
if ((i % 2 == 1) && (i - 1 == prevRay || i + 1 == prevRay)) {
- int jump = min(vW/3, vH/3);
+ int jump = min(vW/3, vH/3); // can add 2 if using medium pinwheel
posx += inc_x * jump;
posy += inc_y * jump;
}
@@ -900,17 +900,32 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
break;
case M12_sPinwheel:
// not 100% accurate, returns outer edge of circle
- int maxXY = max(vW, vH); // max dimension
- int minXY = min(vW, vH); // circle diameter
- float distance = max(1.0f, 0.5f * minXY) -0.5f;
- float centerX = (vW - 1) / 2.0f;
- float centerY = (vH - 1) / 2.0f;
- float angleRad = (maxXY > Pinwheel_Size_Small) ? ((maxXY > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small; // angle in radians
- int x = roundf(centerX + distance * cos_t(angleRad));
- int y = roundf(centerY + distance * sin_t(angleRad));
- // move "slightly off" coordinates back into segment
- x = max(0, min(x, int(vW) - 1));
- y = max(0, min(y, int(vH) - 1));
+ // i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
+ float centerX = roundf((vW-1) / 2.0f);
+ float centerY = roundf((vH-1) / 2.0f);
+ float angleRad = (max(vW, vH) > Pinwheel_Size_Small ? (max(vW, vH) > Pinwheel_Size_Medium ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small); // angle in radians
+ float cosVal = cos_t(angleRad);
+ float sinVal = sin_t(angleRad);
+
+ constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
+ int posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point 18 bit
+ int posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point 18 bit
+ int inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point) 10 bit
+ int inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point) 10 bit
+
+ int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
+ int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
+
+ int x = INT_MIN;
+ int y = INT_MIN;
+ while ((posx >= 0) && (posy >= 0) && (posx < maxX) && (posy < maxY)) {
+ // scale down to integer (compiler will replace division with appropriate bitshift)
+ x = posx / Fixed_Scale;
+ y = posy / Fixed_Scale;
+ // advance to next position
+ posx += inc_x;
+ posy += inc_y;
+ }
return getPixelColorXY(x, y);
break;
}
From ecb861de561673618f5493ebb29fb716cbcf4f21 Mon Sep 17 00:00:00 2001
From: Frank <91616163+softhack007@users.noreply.github.com>
Date: Tue, 14 May 2024 10:36:50 +0200
Subject: [PATCH 12/15] pinwheel code cleanup
reducing code duplication between sPC and gPC
---
wled00/FX_fcn.cpp | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index 3fd9245ea..b5b456feb 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -646,6 +646,12 @@ constexpr int Pinwheel_Steps_Big = 304; // no holes expected up to 56x56
constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...72 to Radians
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...304 to Radians
+constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
+// Pinwheel helper function: pixel index to radians
+static float getPinwheelAngle(int i, int vW, int vH) {
+ int maxXY = max(vW, vH);
+ return (maxXY > Pinwheel_Size_Small) ? ((maxXY > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small;
+}
// 1D strip
uint16_t IRAM_ATTR Segment::virtualLength() const {
@@ -740,7 +746,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
float centerX = roundf((vW-1) / 2.0f);
float centerY = roundf((vH-1) / 2.0f);
- float angleRad = (max(vW, vH) > Pinwheel_Size_Small ? (max(vW, vH) > Pinwheel_Size_Medium ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small); // angle in radians
+ float angleRad = getPinwheelAngle(i, vW, vH); // angle in radians
float cosVal = cos_t(angleRad);
float sinVal = sin_t(angleRad);
@@ -750,7 +756,6 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
// draw line at angle, starting at center and ending at the segment edge
// we use fixed point math for better speed. Starting distance is 0.5 for better rounding
// int_fast16_t and int_fast32_t types changed to int, minimum bits commented
- constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
int posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point 18 bit
int posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point 18 bit
int inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point) 10 bit
@@ -899,23 +904,22 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
return vW>vH ? getPixelColorXY(i, 0) : getPixelColorXY(0, i);
break;
case M12_sPinwheel:
- // not 100% accurate, returns outer edge of circle
+ // not 100% accurate, returns pixel at outer edge
// i = angle --> 0 - 296 (Big), 0 - 192 (Medium), 0 - 72 (Small)
float centerX = roundf((vW-1) / 2.0f);
float centerY = roundf((vH-1) / 2.0f);
- float angleRad = (max(vW, vH) > Pinwheel_Size_Small ? (max(vW, vH) > Pinwheel_Size_Medium ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small); // angle in radians
+ float angleRad = getPinwheelAngle(i, vW, vH); // angle in radians
float cosVal = cos_t(angleRad);
float sinVal = sin_t(angleRad);
- constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
int posx = (centerX + 0.5f * cosVal) * Fixed_Scale; // X starting position in fixed point 18 bit
int posy = (centerY + 0.5f * sinVal) * Fixed_Scale; // Y starting position in fixed point 18 bit
int inc_x = cosVal * Fixed_Scale; // X increment per step (fixed point) 10 bit
int inc_y = sinVal * Fixed_Scale; // Y increment per step (fixed point) 10 bit
-
int32_t maxX = vW * Fixed_Scale; // X edge in fixedpoint
int32_t maxY = vH * Fixed_Scale; // Y edge in fixedpoint
+ // trace ray from center until we hit any edge - to avoid rounding problems, we use the same method as in setPixelColor
int x = INT_MIN;
int y = INT_MIN;
while ((posx >= 0) && (posy >= 0) && (posx < maxX) && (posy < maxY)) {
From a5a6a8eaeea513ce3f4fea51bcc054e4d3d62626 Mon Sep 17 00:00:00 2001
From: Frank <91616163+softhack007@users.noreply.github.com>
Date: Tue, 14 May 2024 11:30:25 +0200
Subject: [PATCH 13/15] pinwheel : fix holes on large matrix, minor code
cleanup
there were still two holes in my 52x52 setup --> added "XL" size for bigger than 50x50 - achieves 18fps on 52x52
---
wled00/FX_fcn.cpp | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index b5b456feb..b31a5e1b8 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -638,20 +638,36 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
}
// Constants for mapping mode "Pinwheel"
+#ifndef WLED_DISABLE_2D
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
-constexpr int Pinwheel_Size_Small = 16;
+constexpr int Pinwheel_Size_Small = 16;
constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32
-constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
-constexpr int Pinwheel_Steps_Big = 304; // no holes expected up to 56x56
+constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
+constexpr int Pinwheel_Steps_Big = 304; // no holes up to 50x50
+constexpr int Pinwheel_Size_Big = 50; // larger than this -> use "XL"
+constexpr int Pinwheel_Steps_XL = 368;
constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...72 to Radians
constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...304 to Radians
+constexpr float Int_to_Rad_XL = (DEG_TO_RAD * 360) / Pinwheel_Steps_XL; // conversion: from 0...368 to Radians
+
constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
+
// Pinwheel helper function: pixel index to radians
static float getPinwheelAngle(int i, int vW, int vH) {
int maxXY = max(vW, vH);
- return (maxXY > Pinwheel_Size_Small) ? ((maxXY > Pinwheel_Size_Medium) ? float(i) * Int_to_Rad_Big : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small;
+ return (maxXY > Pinwheel_Size_Small) ? ((maxXY > Pinwheel_Size_Medium) ? ((maxXY > Pinwheel_Size_Big) ? float(i) * Int_to_Rad_XL : float(i) * Int_to_Rad_Big) : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small;
}
+// Pinwheel helper function: matrix dimensions to number of rays
+static int getPinwheelLength(int vW, int vH) {
+ int maxXY = max(vW, vH);
+ if (maxXY <= Pinwheel_Size_Small) return Pinwheel_Steps_Small;
+ if (maxXY <= Pinwheel_Size_Medium) return Pinwheel_Steps_Medium;
+ if (maxXY <= Pinwheel_Size_Big) return Pinwheel_Steps_Big;
+ // else
+ return Pinwheel_Steps_XL;
+}
+#endif
// 1D strip
uint16_t IRAM_ATTR Segment::virtualLength() const {
@@ -669,12 +685,7 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
vLen = max(vW,vH); // get the longest dimension
break;
case M12_sPinwheel:
- if (max(vW,vH) <= Pinwheel_Size_Small)
- vLen = Pinwheel_Steps_Small;
- else if (max(vW,vH) <= Pinwheel_Size_Medium)
- vLen = Pinwheel_Steps_Medium;
- else
- vLen = Pinwheel_Steps_Big;
+ vLen = getPinwheelLength(vW, vH);
break;
}
return vLen;
From c0cb677a4cf33a8244344d8269790ad46fdb5cb8 Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Tue, 14 May 2024 11:30:33 -0400
Subject: [PATCH 14/15] Pinwheel cleanup
---
wled00/FX_fcn.cpp | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index b31a5e1b8..e3dcc2c0d 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -640,23 +640,27 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
// Constants for mapping mode "Pinwheel"
#ifndef WLED_DISABLE_2D
constexpr int Pinwheel_Steps_Small = 72; // no holes up to 16x16
-constexpr int Pinwheel_Size_Small = 16;
+constexpr int Pinwheel_Size_Small = 16; // larger than this -> use "Medium"
constexpr int Pinwheel_Steps_Medium = 192; // no holes up to 32x32
constexpr int Pinwheel_Size_Medium = 32; // larger than this -> use "Big"
constexpr int Pinwheel_Steps_Big = 304; // no holes up to 50x50
constexpr int Pinwheel_Size_Big = 50; // larger than this -> use "XL"
constexpr int Pinwheel_Steps_XL = 368;
constexpr float Int_to_Rad_Small = (DEG_TO_RAD * 360) / Pinwheel_Steps_Small; // conversion: from 0...72 to Radians
-constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
-constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...304 to Radians
-constexpr float Int_to_Rad_XL = (DEG_TO_RAD * 360) / Pinwheel_Steps_XL; // conversion: from 0...368 to Radians
+constexpr float Int_to_Rad_Med = (DEG_TO_RAD * 360) / Pinwheel_Steps_Medium; // conversion: from 0...192 to Radians
+constexpr float Int_to_Rad_Big = (DEG_TO_RAD * 360) / Pinwheel_Steps_Big; // conversion: from 0...304 to Radians
+constexpr float Int_to_Rad_XL = (DEG_TO_RAD * 360) / Pinwheel_Steps_XL; // conversion: from 0...368 to Radians
constexpr int Fixed_Scale = 512; // fixpoint scaling factor (9bit for fraction)
// Pinwheel helper function: pixel index to radians
static float getPinwheelAngle(int i, int vW, int vH) {
int maxXY = max(vW, vH);
- return (maxXY > Pinwheel_Size_Small) ? ((maxXY > Pinwheel_Size_Medium) ? ((maxXY > Pinwheel_Size_Big) ? float(i) * Int_to_Rad_XL : float(i) * Int_to_Rad_Big) : float(i) * Int_to_Rad_Med) : float(i) * Int_to_Rad_Small;
+ if (maxXY <= Pinwheel_Size_Small) return float(i) * Int_to_Rad_Small;
+ if (maxXY <= Pinwheel_Size_Medium) return float(i) * Int_to_Rad_Med;
+ if (maxXY <= Pinwheel_Size_Big) return float(i) * Int_to_Rad_Big;
+ // else
+ return Pinwheel_Steps_XL;
}
// Pinwheel helper function: matrix dimensions to number of rays
static int getPinwheelLength(int vW, int vH) {
From 3cb6b173163ad3311b8d6063c01c7c1b74dedfd0 Mon Sep 17 00:00:00 2001
From: Brandon502 <105077712+Brandon502@users.noreply.github.com>
Date: Tue, 14 May 2024 11:46:52 -0400
Subject: [PATCH 15/15] Pinwheel fix
---
wled00/FX_fcn.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp
index e3dcc2c0d..ef710b0b8 100644
--- a/wled00/FX_fcn.cpp
+++ b/wled00/FX_fcn.cpp
@@ -660,7 +660,7 @@ static float getPinwheelAngle(int i, int vW, int vH) {
if (maxXY <= Pinwheel_Size_Medium) return float(i) * Int_to_Rad_Med;
if (maxXY <= Pinwheel_Size_Big) return float(i) * Int_to_Rad_Big;
// else
- return Pinwheel_Steps_XL;
+ return float(i) * Int_to_Rad_XL;
}
// Pinwheel helper function: matrix dimensions to number of rays
static int getPinwheelLength(int vW, int vH) {