/*
Simple "Hello World" for ILI9341 LCD
https://wokwi.com/arduino/projects/308024602434470466
*/
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#define TFT_DC 9
#define TFT_CS 10
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
uint16_t rgbTo565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3);
}
void brezLine(int x0, int y0, int x1, int y1, bool add, void* ctx, void (*set)(int x, int y, void* ctx)) {
int dx = x1 - x0;
int dy = y1 - y0;
int i = 0;
int sx = 1, sy = 1;
if (dx < 0) dx = -dx, sx = -1;
if (dy < 0) dy = -dy, sy = -1;
int dx2 = dx * 2;
int dy2 = dy * 2;
set(x0, y0, ctx);
if (dx > dy) {
int err = dy2 - dx;
while (x0 != x1) {
x0 += sx;
if (err >= 0) {
y0 += sy;
err -= dx2;
if (add) set(x0 - sx, y0, ctx);
}
err += dy2;
set(x0, y0, ctx);
}
} else {
int err = dx2 - dy;
while (y0 != y1) {
y0 += sy;
if (err >= 0) {
x0 += sx;
err -= dy2;
if (add) set(x0, y0 - sy, ctx);
}
err += dx2;
set(x0, y0, ctx);
}
}
}
void point(int x, int y, uint16_t color) {
tft.drawPixel(x, y, color);
}
void fillGradient(int x0, int y0, int w, int h, int angle) {
struct GradData {
GradData(int x0, int y0, int w, int h, int angle) : x0(x0), y0(y0), w(w), h(h) {
hypot = sqrt(w * w + h * h) / 2;
cx = x0 + w / 2;
cy = y0 + h / 2;
sx = cos(radians(angle)) * hypot;
sy = sin(radians(angle)) * hypot;
len = sqrt(sx * sx + sy * sy) * 2;
}
uint16_t hypot;
int16_t cx, cy;
int16_t sx, sy;
int16_t x0, y0;
uint16_t w, h;
uint16_t i = 0, len, color;
};
GradData data(x0, y0, w, h, angle);
brezLine(data.cx - data.sx, data.cy + data.sy, data.cx + data.sx, data.cy - data.sy, false, &data, [](int x, int y, void* vdata) {
GradData& data = *((GradData*)vdata);
data.color = rgbTo565(data.i * 255 / data.len, 0, (data.len - data.i) * 255 / data.len);
data.i++;
brezLine(x - data.sy, y - data.sx, x + data.sy, y + data.sx, true, &data, [](int x, int y, void* vdata) {
GradData& data = *((GradData*)vdata);
if (x >= data.x0 && x < (data.x0 + data.w) && y >= data.y0 && y < (data.y0 + data.h)) {
point(x, y, data.color);
}
});
});
}
void setup() {
tft.begin();
}
int angle = 0;
void loop() {
// tft.fillScreen(ILI9341_BLACK);
tft.fillRect(0, 0, 100, 100, ILI9341_BLACK);
tft.drawRect(20, 20, 40, 60, 0x0ff0);
fillGradient(20, 20, 40, 60, angle);
angle += 10;
if (angle >= 180) angle = -180;
delay(100);
}