#pragma once #include #include "datatypes.cpp" namespace UwU { class Helpers { public: static uint8_t lerp8(uint8_t a, uint8_t b, uint8_t t) { uint16_t product = (a * (255 - t)) + (b * t); return product / 255; } static Color lerpColor(Color a, Color b, uint8_t t) { Color mixed = Color(); mixed.r = lerp8(a.r, b.r, t); mixed.g = lerp8(a.g, b.g, t); mixed.b = lerp8(a.b, b.b, t); mixed.a = lerp8(a.a, b.a, t); // maybe the alpha channel should be handled differently? return mixed; } static void bresenhamLow(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) { int16_t dx = int16_t(x1) - int16_t(x0); int16_t dy = y1 - y0; int16_t yi = 1; if (dy < 0) { yi = -1; dy = -dy; } int16_t d = (2 * dy) - dx; int16_t y = y0; for (uint16_t x = x0; x <= x1; x++) { LUT[x] = y; if (d > 0) { y += yi; d += (2 * (dy - dx)); } else { d += (2 * dy); } } return; } static void bresenhamHigh(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) { int16_t dx = (int16_t)x1 - (int16_t)x0; int16_t dy = y1 - y0; int16_t xi = 1; if (dx < 0) { xi = -1; dx = -dx; } int16_t d = (2 * dx) - dy; int16_t x = (int16_t)x0; for (int16_t y = y0; y <= y1; y++) { LUT[x] = y; if (d > 0) { x += xi; d += (2 * (dx - dy)); } else { d += (2 * dx); } } return; } // x1 must >= x0 && LUT must be size x1 + 1 static void bresenham(uint16_t x0, int16_t y0, uint16_t x1, int16_t y1, int16_t* LUT) { if (x0 == x1) { // catch vline condition LUT[x0] = y1; return; } if (y0 == y1) { // catch hline condition for (uint16_t i = x0; i <= x1; i++) { LUT[i] = y1; } return; } if (abs(y1 - y0) <= abs(x1 - x0)) { bresenhamLow(x0, y0, x1, y1, LUT); } else { if (y0 > y1) { bresenhamHigh(x1, y1, x0, y0, LUT); } else { bresenhamHigh(x0, y0, x1, y1, LUT); } } return; } }; }