fix(display): render authentic mathematical wedge polygons for arc during slide transition

This commit is contained in:
Sebastián Nieto 2026-09-22 00:33:26 -03:00
parent be9687c845
commit 3c18eb78ac

View file

@ -1276,6 +1276,59 @@ inline void drawPidIconToSprite(TFT_eSprite &s, int ix, int iy, const String &pi
}
}
// Draw an individual solid curved block into sprite slice with subpixel anti-aliasing
inline void drawQuadBarBlockToSprite(TFT_eSprite &s, int16_t qx, int16_t qy, uint8_t i, uint16_t color, int slice_h) {
int16_t minX = pgm_read_word(&quadBlockMinX[i]);
int16_t maxX = pgm_read_word(&quadBlockMaxX[i]);
int16_t minY = pgm_read_word(&quadBlockMinY[i]);
int16_t maxY = pgm_read_word(&quadBlockMaxY[i]);
if (qx + maxX < 0 || qx + minX >= 320) return;
if (qy + maxY < 0 || qy + minY >= slice_h) return;
int16_t startY = minY;
int16_t endY = maxY;
if (qy + startY < 0) startY = -qy;
if (qy + endY >= slice_h) endY = slice_h - 1 - qy;
int16_t startX = minX;
int16_t endX = maxX;
if (qx + startX < 0) startX = -qx;
if (qx + endX >= 320) endX = 319 - qx;
float nx[4], ny[4], c[4];
for (uint8_t k = 0; k < 4; k++) {
nx[k] = pgm_read_float(&quadBlockNx[i][k]);
ny[k] = pgm_read_float(&quadBlockNy[i][k]);
c[k] = pgm_read_float(&quadBlockC[i][k]);
}
for (int16_t y = startY; y <= endY; y++) {
float py = (float)y + 0.5f;
int16_t sy = qy + y;
for (int16_t x = startX; x <= endX; x++) {
float px = (float)x + 0.5f;
float min_d = 999.0f;
for (uint8_t k = 0; k < 4; k++) {
float d = px * nx[k] + py * ny[k] + c[k];
if (d < min_d) min_d = d;
}
if (min_d <= -0.5f) continue;
int16_t sx = qx + x;
if (color == TFT_BLACK) {
s.drawPixel(sx, sy, TFT_BLACK);
} else {
if (min_d >= 0.5f) {
s.drawPixel(sx, sy, color);
} else {
uint8_t alpha = (uint8_t)((min_d + 0.5f) * 255.0f);
s.drawPixel(sx, sy, fastBlend(alpha, color, (uint16_t)TFT_BLACK));
}
}
}
}
}
// Render Page 0 (4 Quadrants) into double-buffered Sprite slice
inline void renderPage0ToSprite(TFT_eSprite &s, int x_offset, int y_slice, int slice_h) {
checkUpdateThemeGradients();
@ -1306,7 +1359,7 @@ inline void renderPage0ToSprite(TFT_eSprite &s, int x_offset, int y_slice, int s
// 2. Real high-definition parameter icon (thermometer, speedometer, tachometer, battery)
drawPidIconToSprite(s, qx + 5, qy + 3, pidConfig[pidIdx][2], slice_h);
// 3. Exact 20 curved segmented gauge blocks along the arc
// 3. Exact 20 curved segmented gauge blocks along the arc (true mathematical polygons)
int warn = warningValue[pidIdx].toInt();
int min = pidConfig[pidIdx][4].toInt();
int max = pidConfig[pidIdx][5].toInt();
@ -1317,15 +1370,8 @@ inline void renderPage0ToSprite(TFT_eSprite &s, int x_offset, int y_slice, int s
uint16_t activeCol = (val > -900.0f) ? getMeterColor(pidIdx, val, warn) : priCol;
for (uint8_t i = 0; i < NUM_BAR_BLOCKS; i++) {
int bx = qx + pgm_read_word(&quadBlockMinX[i]);
int by = qy + pgm_read_word(&quadBlockMinY[i]);
int bw = pgm_read_word(&quadBlockMaxX[i]) - pgm_read_word(&quadBlockMinX[i]) + 1;
int bh = pgm_read_word(&quadBlockMaxY[i]) - pgm_read_word(&quadBlockMinY[i]) + 1;
if (by + bh <= 0 || by >= slice_h || bx + bw <= 0 || bx >= 320) continue;
uint16_t bCol = (i < numActive) ? activeCol : METER_INACTIVE_COLOR;
s.fillRoundRect(bx, by, bw, bh, 2, bCol);
drawQuadBarBlockToSprite(s, qx, qy, i, bCol, slice_h);
}
// 4. Digital value string