Added Pinwheel Expand 1D Effect

This commit is contained in:
Brandon502 2024-05-07 18:04:29 -04:00
parent a6e536189c
commit da79b93387
3 changed files with 60 additions and 2 deletions

View File

@ -320,7 +320,8 @@ typedef enum mapping1D2D {
M12_Pixels = 0, M12_Pixels = 0,
M12_pBar = 1, M12_pBar = 1,
M12_pArc = 2, M12_pArc = 2,
M12_pCorner = 3 M12_pCorner = 3,
M12_sPinwheel = 4
} mapping1D2D_t; } mapping1D2D_t;
// segment, 80 bytes // segment, 80 bytes

View File

@ -637,6 +637,14 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const {
return vLen; 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 // 1D strip
uint16_t IRAM_ATTR Segment::virtualLength() const { uint16_t IRAM_ATTR Segment::virtualLength() const {
#ifndef WLED_DISABLE_2D #ifndef WLED_DISABLE_2D
@ -652,6 +660,12 @@ uint16_t IRAM_ATTR Segment::virtualLength() const {
case M12_pArc: case M12_pArc:
vLen = max(vW,vH); // get the longest dimension vLen = max(vW,vH); // get the longest dimension
break; break;
case M12_sPinwheel:
if (max(vW,vH) <= Pinwheel_Size_Medium)
vLen = Pinwheel_Steps_Medium;
else
vLen = Pinwheel_Steps_Big;
break;
} }
return vLen; 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 x = 0; x <= i; x++) setPixelColorXY(x, i, col);
for (int y = 0; y < i; y++) setPixelColorXY(i, y, col); for (int y = 0; y < i; y++) setPixelColorXY(i, y, col);
break; 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; return;
} else if (Segment::maxHeight!=1 && (width()==1 || height()==1)) { } else if (Segment::maxHeight!=1 && (width()==1 || height()==1)) {
@ -833,7 +879,17 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i)
// use longest dimension // use longest dimension
return vW>vH ? getPixelColorXY(i, 0) : getPixelColorXY(0, i); return vW>vH ? getPixelColorXY(i, 0) : getPixelColorXY(0, i);
break; 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; return 0;
} }
#endif #endif

View File

@ -801,6 +801,7 @@ function populateSegments(s)
`<option value="1" ${inst.m12==1?' selected':''}>Bar</option>`+ `<option value="1" ${inst.m12==1?' selected':''}>Bar</option>`+
`<option value="2" ${inst.m12==2?' selected':''}>Arc</option>`+ `<option value="2" ${inst.m12==2?' selected':''}>Arc</option>`+
`<option value="3" ${inst.m12==3?' selected':''}>Corner</option>`+ `<option value="3" ${inst.m12==3?' selected':''}>Corner</option>`+
`<option value="4" ${inst.m12==4?' selected':''}>Pinwheel</option>`+
`</select></div>`+ `</select></div>`+
`</div>`; `</div>`;
let sndSim = `<div data-snd="si" class="lbl-s hide">Sound sim<br>`+ let sndSim = `<div data-snd="si" class="lbl-s hide">Sound sim<br>`+