/* Open and filled triangles and quadrilaterals - see http://www.technoblogy.com/show?3ZYQ David Johnson-Davies - www.technoblogy.com - 15th August 2022 CC BY 4.0 Licensed under a Creative Commons Attribution 4.0 International license: http://creativecommons.org/licenses/by/4.0/ */ #define swap(a, b) { a = a ^ b; b = b ^ a; a = a ^ b; } void DrawQuad(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3) { MoveTo(x0, y0); DrawTo(x1, y1); DrawTo(x2, y2); DrawTo(x3, y3); DrawTo(x0, y0); } void DrawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { MoveTo(x0, y0); DrawTo(x1, y1); DrawTo(x2, y2); DrawTo(x0, y0); } void FillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2) { // Sort coordinates by y order (y2 >= y1 >= y0) if (y0 > y1) { swap(y0, y1); swap(x0, x1); } if (y1 > y2) { swap(y1, y2); swap(x1, x2); } if (y0 > y1) { swap(y0, y1); swap(x0, x1); } TriangleQuad(x0, y0, x1, y1, x2, y2, x2, y2); } void FillQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3) { // Sort coordinates by y order (y3 >= y2 >= y1 >= y0) if (y0 > y1) { swap(y0, y1); swap(x0, x1); } if (y2 > y3) { swap(y2, y3); swap(x2, x3); } if (y1 > y3) { swap(y1, y3); swap(x1, x3); } if (y0 > y2) { swap(y0, y2); swap(x0, x2); } if (y1 > y2) { swap(y1, y2); swap(x1, x2); } TriangleQuad(x0, y0, x1, y1, x2, y2, x3, y3); } void TriangleQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3) { // Coordinates already in y order (y3 >= y2 >= y1 >= y0) int16_t a, b, y; // Special case? int16_t x4 = x0 + (x3 - x0) * (y1 - y0) / (y3 - y0); int16_t x5 = x0 + (x3 - x0) * (y2 - y0) / (y3 - y0); if ((x5 > x2) == (x4 > x1)) { swap(x2, x5); } else { // Kite x4 = x0 + (x2 - x0) * (y1 - y0) / (y2 - y0); x5 = x1 + (x3 - x1) * (y2 - y1) / (y3 - y1); } // Fill bottom section for (y = y0; y <= y1; y++) { a = x0 + (x4 - x0) * (y - y0) / (y1 - y0); b = x0 + (x1 - x0) * (y - y0) / (y1 - y0); if (a > b) swap(a, b); // MoveTo(a, y); DrawTo(b, y); MoveTo(a, y); FillRect(b - a + 1, 1); } // Fill middle section for (; y <= y2; y++) { a = x4 + (x2 - x4) * (y - y1) / (y2 - y1); b = x1 + (x5 - x1) * (y - y1) / (y2 - y1); if (a > b) swap(a, b); // MoveTo(a, y); DrawTo(b, y); MoveTo(a, y); FillRect(b - a + 1, 1); } // Fill top section for (; y <= y3; y++) { a = x2 + (x3 - x2) * (y - y2) / (y3 - y2); b = x5 + (x3 - x5) * (y - y2) / (y3 - y2); if (a > b) swap(a, b); // MoveTo(a, y); DrawTo(b, y); MoveTo(a, y); FillRect(b - a + 1, 1); } } // Demo ********************************************** void Cubes () { int h = 21, w = 36, x0 = 120, y0 = 100; for (int y=y0, i=2; y<=y0+h*6; y=y+h*3, i--) { for (int x=x0-w*i; x<=x0+w*i; x = x+w*2) { fore = Colour(255, 8, 8); // Red FillQuad(x, y, x - w, y - h, x, y - h*2, x + w, y - h); fore = Colour(16, 16, 255); // Blue FillQuad(x - w, y - h, x, y - h*2, x, y - h*4, x - w, y - h*3); fore = Colour(192, 128, 0); // Orange FillQuad(x, y - h*2, x, y - h*4, x + w, y - h*3 ,x + w, y - h); } } }