From 8ed8b44b0216e721480be3068145a879c1101d24 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Fri, 7 Nov 2025 09:39:44 -0500 Subject: [PATCH 01/14] Add rotated rectangle draw and fill methods --- Adafruit_GFX.cpp | 105 +++++++++++++++++++++++++++++++++++++++++++++++ Adafruit_GFX.h | 7 ++++ 2 files changed, 112 insertions(+) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index 5b33ee41..8995ccd9 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -700,6 +700,111 @@ void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, endWrite(); } +/**************************************************************************/ +/*! + @brief Draw a rotated rectangle + @param cenX x coordinate of center of rectangle + @param cenY y coordinate of center of rectangle + @param width width of rectangle + @param height height of rectangle + @param angleDeg angle of rotation of rectangle + @param color 16-bit 5-6-5 Color to fill/draw with +*/ +/**************************************************************************/ +void Adafruit_GFX::drawRotatedRectangle(int16_t cenX, int16_t cenY, + int16_t width, int16_t height, + int16_t angleDeg, uint16_t color) { + + int16_t halfW = width / 2.0; + int16_t halfH = height / 2.0; + + int16_t x0 = cenX - halfW; // top-left + int16_t y0 = cenY - halfH; // top-left + int16_t x1 = cenX + halfW; // top-right + int16_t y1 = cenY - halfH; // top-right + int16_t x2 = cenX - halfW; // bottom-left + int16_t y2 = cenY + halfH; // bottom-left + int16_t x3 = cenX + halfW; // bottom-right + int16_t y3 = cenY + halfH; // bottom-right + + rotatePoint(x0, y0, cenX, cenY, angleDeg); + rotatePoint(x1, y1, cenX, cenY, angleDeg); + rotatePoint(x2, y2, cenX, cenY, angleDeg); + rotatePoint(x3, y3, cenX, cenY, angleDeg); + + drawLine(x0, y0, x1, y1, color); // top left to top right + drawLine(x0, y0, x2, y2, color); // top left to bottom left + drawLine(x1, y1, x3, y3, color); // top right to bottom right + drawLine(x2, y2, x3, y3, color); // bottom left to bottom right + +} + +/**************************************************************************/ +/*! + @brief Draw a filled rotated rectangle + @param cenX x coordinate of center of rectangle + @param cenY y coordinate of center of rectangle + @param width width of rectangle + @param height height of rectangle + @param angleDeg angle of rotation of rectangle + @param color 16-bit 5-6-5 Color to fill/draw with +*/ +/**************************************************************************/ +void Adafruit_GFX::fillRotatedRectangle(int16_t cenX, int16_t cenY, + int16_t width, int16_t height, + int16_t angleDeg, uint16_t color) { + + int16_t halfW = width / 2.0; + int16_t halfH = height / 2.0; + + int16_t x0 = cenX - halfW; // top-left + int16_t y0 = cenY - halfH; // top-left + int16_t x1 = cenX + halfW; // top-right + int16_t y1 = cenY - halfH; // top-right + int16_t x2 = cenX - halfW; // bottom-left + int16_t y2 = cenY + halfH; // bottom-left + int16_t x3 = cenX + halfW; // bottom-right + int16_t y3 = cenY + halfH; // bottom-right + + rotatePoint(x0, y0, cenX, cenY, angleDeg); + rotatePoint(x1, y1, cenX, cenY, angleDeg); + rotatePoint(x2, y2, cenX, cenY, angleDeg); + rotatePoint(x3, y3, cenX, cenY, angleDeg); + + fillTriangle(x0, y0, x1, y1, x2, y2, color); + fillTriangle(x1, y1, x2, y2, x3, y3, color); +} + +/**************************************************************************/ +/*! + @brief Rotate a point around another point + @param x0 x coordinate of point to rotate. This is passed by reference + and updated upon return + @param y0 y coordinate of point to rotate. This is passed by reference + and updated upon return + @param orgX width of rectangle + @param orgY height of rectangle + @param angleDeg angle of rotation of rectangle +*/ +/**************************************************************************/ +void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, int16_t angleDeg) { + float angleRad = radians(angleDeg); + float s = sin(angleRad); + float c = cos(angleRad); + + // Translate to standard position + int16_t xStan = x0 - orgX; + int16_t yStan = y0 - orgY; + + // Rotate point + int16_t xRot = (int16_t)((float)xStan * c - (float)yStan * s); + int16_t yRot = (int16_t)((float)xStan * s + (float)yStan * c); + + // Translate back + x0 = xRot + orgX; + y0 = yRot + orgY; +} + /**************************************************************************/ /*! @brief Draw a triangle with no fill color diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index 032d8ea4..e61d1250 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -85,6 +85,13 @@ class Adafruit_GFX : public Print { int16_t radius, uint16_t color); void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color); + void drawRotatedRectangle(int16_t cenX, int16_t cenY, + int16_t width, int16_t height, + int16_t angleDeg, uint16_t color); + void fillRotatedRectangle(int16_t cenX, int16_t cenY, + int16_t width, int16_t height, + int16_t angleDeg, uint16_t color); + void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, int16_t angleDeg); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, From 6e8024a758109a10f4f351487edbeffc8560e48e Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Fri, 7 Nov 2025 09:55:15 -0500 Subject: [PATCH 02/14] Add rotated rectangle draw and fill methods (formatting) --- Adafruit_GFX.cpp | 16 ++++++++-------- Adafruit_GFX.h | 13 ++++++------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index 8995ccd9..84c4b59c 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -712,8 +712,8 @@ void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, */ /**************************************************************************/ void Adafruit_GFX::drawRotatedRectangle(int16_t cenX, int16_t cenY, - int16_t width, int16_t height, - int16_t angleDeg, uint16_t color) { + int16_t width, int16_t height, + int16_t angleDeg, uint16_t color) { int16_t halfW = width / 2.0; int16_t halfH = height / 2.0; @@ -731,12 +731,11 @@ void Adafruit_GFX::drawRotatedRectangle(int16_t cenX, int16_t cenY, rotatePoint(x1, y1, cenX, cenY, angleDeg); rotatePoint(x2, y2, cenX, cenY, angleDeg); rotatePoint(x3, y3, cenX, cenY, angleDeg); - + drawLine(x0, y0, x1, y1, color); // top left to top right drawLine(x0, y0, x2, y2, color); // top left to bottom left drawLine(x1, y1, x3, y3, color); // top right to bottom right drawLine(x2, y2, x3, y3, color); // bottom left to bottom right - } /**************************************************************************/ @@ -751,8 +750,8 @@ void Adafruit_GFX::drawRotatedRectangle(int16_t cenX, int16_t cenY, */ /**************************************************************************/ void Adafruit_GFX::fillRotatedRectangle(int16_t cenX, int16_t cenY, - int16_t width, int16_t height, - int16_t angleDeg, uint16_t color) { + int16_t width, int16_t height, + int16_t angleDeg, uint16_t color) { int16_t halfW = width / 2.0; int16_t halfH = height / 2.0; @@ -770,7 +769,7 @@ void Adafruit_GFX::fillRotatedRectangle(int16_t cenX, int16_t cenY, rotatePoint(x1, y1, cenX, cenY, angleDeg); rotatePoint(x2, y2, cenX, cenY, angleDeg); rotatePoint(x3, y3, cenX, cenY, angleDeg); - + fillTriangle(x0, y0, x1, y1, x2, y2, color); fillTriangle(x1, y1, x2, y2, x3, y3, color); } @@ -787,7 +786,8 @@ void Adafruit_GFX::fillRotatedRectangle(int16_t cenX, int16_t cenY, @param angleDeg angle of rotation of rectangle */ /**************************************************************************/ -void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, int16_t angleDeg) { +void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, + int16_t orgY, int16_t angleDeg) { float angleRad = radians(angleDeg); float s = sin(angleRad); float c = cos(angleRad); diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index e61d1250..86ddc5af 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -85,13 +85,12 @@ class Adafruit_GFX : public Print { int16_t radius, uint16_t color); void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color); - void drawRotatedRectangle(int16_t cenX, int16_t cenY, - int16_t width, int16_t height, - int16_t angleDeg, uint16_t color); - void fillRotatedRectangle(int16_t cenX, int16_t cenY, - int16_t width, int16_t height, - int16_t angleDeg, uint16_t color); - void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, int16_t angleDeg); + void drawRotatedRectangle(int16_t cenX, int16_t cenY, int16_t width, + int16_t height, int16_t angleDeg, uint16_t color); + void fillRotatedRectangle(int16_t cenX, int16_t cenY, int16_t width, + int16_t height, int16_t angleDeg, uint16_t color); + void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, + int16_t angleDeg); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, From 0cd6f9c589286af571e5c52f0999f106a0f952d1 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Fri, 7 Nov 2025 13:43:55 -0500 Subject: [PATCH 03/14] Add rotated rectangle draw and fill methods (remove unnecessary floats and correct brief) --- Adafruit_GFX.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index 84c4b59c..83f60c8e 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -715,8 +715,8 @@ void Adafruit_GFX::drawRotatedRectangle(int16_t cenX, int16_t cenY, int16_t width, int16_t height, int16_t angleDeg, uint16_t color) { - int16_t halfW = width / 2.0; - int16_t halfH = height / 2.0; + int16_t halfW = width / 2; + int16_t halfH = height / 2; int16_t x0 = cenX - halfW; // top-left int16_t y0 = cenY - halfH; // top-left @@ -753,8 +753,8 @@ void Adafruit_GFX::fillRotatedRectangle(int16_t cenX, int16_t cenY, int16_t width, int16_t height, int16_t angleDeg, uint16_t color) { - int16_t halfW = width / 2.0; - int16_t halfH = height / 2.0; + int16_t halfW = width / 2; + int16_t halfH = height / 2; int16_t x0 = cenX - halfW; // top-left int16_t y0 = cenY - halfH; // top-left @@ -781,8 +781,8 @@ void Adafruit_GFX::fillRotatedRectangle(int16_t cenX, int16_t cenY, and updated upon return @param y0 y coordinate of point to rotate. This is passed by reference and updated upon return - @param orgX width of rectangle - @param orgY height of rectangle + @param orgX x coordinate of point to be rotated around + @param orgY y coordinate of point to be rotated around @param angleDeg angle of rotation of rectangle */ /**************************************************************************/ From 64342932f5b8f754b060731bb79aa4fa0507ef6f Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Fri, 7 Nov 2025 14:18:23 -0500 Subject: [PATCH 04/14] Added example --- .../RotatedRectangleTest.ino | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 examples/RotatedRectangleTest/RotatedRectangleTest.ino diff --git a/examples/RotatedRectangleTest/RotatedRectangleTest.ino b/examples/RotatedRectangleTest/RotatedRectangleTest.ino new file mode 100644 index 00000000..aa226eb5 --- /dev/null +++ b/examples/RotatedRectangleTest/RotatedRectangleTest.ino @@ -0,0 +1,52 @@ +#include +#include +#include + +#define TFT_RST D0 +#define TFT_DC D1 +#define TFT_CS D2 +#define TFT_BACKLIGHT D3 +#define SPI_SPEED 40000000 +#define ROTATION 1 + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 128 + +#define SERIAL_SPEED 9600 + +Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST); +GFXcanvas16 canvas = GFXcanvas16(SCREEN_WIDTH, SCREEN_HEIGHT); + +int16_t angle = 0; + +void setup(void) +{ + Serial.begin(SERIAL_SPEED); + Serial.println("Start up."); + initializeTFT(); +} + +void loop() +{ + canvas.fillScreen(ST77XX_BLACK); + canvas.drawRotatedRectangle(44, 44, 40, 30, angle, 0xFFFF); + canvas.fillRotatedRectangle(84, 84, 40, 30, angle, ST77XX_GREEN); + tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); + ++angle %= 360; +} + +void initializeTFT(void) +{ + pinMode(TFT_BACKLIGHT, OUTPUT); + digitalWrite(TFT_BACKLIGHT, HIGH); + tft.init(SCREEN_WIDTH, SCREEN_HEIGHT); + tft.setSPISpeed(SPI_SPEED); + tft.setRotation(ROTATION); + tft.fillScreen(ST77XX_BLACK); + tft.setCursor(0, 0); + tft.setTextColor(ST77XX_WHITE); + tft.setTextSize(1); + + Serial.println("TFT initialized."); + tft.println("TFT initialized."); +} From 47ac9d99afc03622df37bc6620073c46ad754fe9 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Fri, 7 Nov 2025 14:37:08 -0500 Subject: [PATCH 05/14] Added example (attempt to address breaks) --- examples/RotatedRectangleTest/RotatedRectangleTest.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/RotatedRectangleTest/RotatedRectangleTest.ino b/examples/RotatedRectangleTest/RotatedRectangleTest.ino index aa226eb5..6917ce79 100644 --- a/examples/RotatedRectangleTest/RotatedRectangleTest.ino +++ b/examples/RotatedRectangleTest/RotatedRectangleTest.ino @@ -9,8 +9,8 @@ #define SPI_SPEED 40000000 #define ROTATION 1 -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 128 +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 #define SERIAL_SPEED 9600 From dbd3614ec1b3b159ea8fdb4f4d2efc207200a273 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Fri, 7 Nov 2025 15:02:12 -0500 Subject: [PATCH 06/14] Added example (attempt to address breaks) --- examples/RotatedRectangleTest/RotatedRectangleTest.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/RotatedRectangleTest/RotatedRectangleTest.ino b/examples/RotatedRectangleTest/RotatedRectangleTest.ino index 6917ce79..aa226eb5 100644 --- a/examples/RotatedRectangleTest/RotatedRectangleTest.ino +++ b/examples/RotatedRectangleTest/RotatedRectangleTest.ino @@ -9,8 +9,8 @@ #define SPI_SPEED 40000000 #define ROTATION 1 -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 240 +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 128 #define SERIAL_SPEED 9600 From 4f7ff5e52228457552560af8e9fe9d1b32795816 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Sun, 9 Nov 2025 10:13:16 -0500 Subject: [PATCH 07/14] Updated naming for consistency and example file --- Adafruit_GFX.cpp | 28 ++++---- Adafruit_GFX.h | 8 +-- examples/RotatedRectTest/RotatedRectTest.ino | 67 +++++++++++++++++++ .../RotatedRectangleTest.ino | 52 -------------- 4 files changed, 85 insertions(+), 70 deletions(-) create mode 100644 examples/RotatedRectTest/RotatedRectTest.ino delete mode 100644 examples/RotatedRectangleTest/RotatedRectangleTest.ino diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index 83f60c8e..680f787c 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -705,18 +705,18 @@ void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, @brief Draw a rotated rectangle @param cenX x coordinate of center of rectangle @param cenY y coordinate of center of rectangle - @param width width of rectangle - @param height height of rectangle + @param w width of rectangle + @param h height of rectangle @param angleDeg angle of rotation of rectangle @param color 16-bit 5-6-5 Color to fill/draw with */ /**************************************************************************/ -void Adafruit_GFX::drawRotatedRectangle(int16_t cenX, int16_t cenY, - int16_t width, int16_t height, - int16_t angleDeg, uint16_t color) { +void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, + int16_t w, int16_t h, + int16_t angleDeg, uint16_t color) { - int16_t halfW = width / 2; - int16_t halfH = height / 2; + int16_t halfW = w / 2; + int16_t halfH = h / 2; int16_t x0 = cenX - halfW; // top-left int16_t y0 = cenY - halfH; // top-left @@ -743,18 +743,18 @@ void Adafruit_GFX::drawRotatedRectangle(int16_t cenX, int16_t cenY, @brief Draw a filled rotated rectangle @param cenX x coordinate of center of rectangle @param cenY y coordinate of center of rectangle - @param width width of rectangle - @param height height of rectangle + @param w width of rectangle + @param h height of rectangle @param angleDeg angle of rotation of rectangle @param color 16-bit 5-6-5 Color to fill/draw with */ /**************************************************************************/ -void Adafruit_GFX::fillRotatedRectangle(int16_t cenX, int16_t cenY, - int16_t width, int16_t height, - int16_t angleDeg, uint16_t color) { +void Adafruit_GFX::fillRotatedRect(int16_t cenX, int16_t cenY, + int16_t w, int16_t h, + int16_t angleDeg, uint16_t color) { - int16_t halfW = width / 2; - int16_t halfH = height / 2; + int16_t halfW = w / 2; + int16_t halfH = h / 2; int16_t x0 = cenX - halfW; // top-left int16_t y0 = cenY - halfH; // top-left diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index 86ddc5af..53e8bd43 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -85,10 +85,10 @@ class Adafruit_GFX : public Print { int16_t radius, uint16_t color); void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color); - void drawRotatedRectangle(int16_t cenX, int16_t cenY, int16_t width, - int16_t height, int16_t angleDeg, uint16_t color); - void fillRotatedRectangle(int16_t cenX, int16_t cenY, int16_t width, - int16_t height, int16_t angleDeg, uint16_t color); + void drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, + int16_t h, int16_t angleDeg, uint16_t color); + void fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, + int16_t h, int16_t angleDeg, uint16_t color); void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, int16_t angleDeg); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, diff --git a/examples/RotatedRectTest/RotatedRectTest.ino b/examples/RotatedRectTest/RotatedRectTest.ino new file mode 100644 index 00000000..2abf6522 --- /dev/null +++ b/examples/RotatedRectTest/RotatedRectTest.ino @@ -0,0 +1,67 @@ +/*************************************************** + This is an example to exercise the rotated rectangle + methods 'drawRotatedRect' and 'fillRotatedRect'. + The commented lines represent hardware-specific + details that will need to be customized for the + particular display chosen by the end-user. + ****************************************************/ + +// #include +// #include +#include + +// #define TFT_RST D0 +// #define TFT_DC D1 +// #define TFT_CS D2 +// #define TFT_BACKLIGHT D3 +// #define SPI_SPEED 40000000 +// #define ROTATION 1 + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 128 + +#define SERIAL_SPEED 9600 + +#define DRAW_CIRCLE_TOP 44 +#define DRAW_CIRCLE_LEFT 44 +#define FILL_CIRCLE_TOP 84 +#define FILL_CIRCLE_LEFT 84 +#define WIDTH 40 +#define HEIGHT 30 +#define BLACK 0x0000 +#define WHITE 0xFFFF +#define GREEN 0x07E0 + + +//Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST); +GFXcanvas16 canvas = GFXcanvas16(SCREEN_WIDTH, SCREEN_HEIGHT); + +int16_t angle = 0; + +void setup(void) +{ + Serial.begin(SERIAL_SPEED); + Serial.println("Start up."); + initializeTFT(); +} + +void loop() +{ + canvas.fillScreen(BLACK); + canvas.drawRotatedRect(DRAW_CIRCLE_TOP, DRAW_CIRCLE_TOP, WIDTH, HEIGHT, angle, WHITE); + canvas.fillRotatedRect(DRAW_CIRCLE_TOP, DRAW_CIRCLE_TOP, WIDTH, HEIGHT, angle, GREEN); + //Un-comment to display the rotated rectangles on your display + //tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); + ++angle %= 360; +} + +void initializeTFT(void) +{ + // pinMode(TFT_BACKLIGHT, OUTPUT); + // digitalWrite(TFT_BACKLIGHT, HIGH); + // tft.init(SCREEN_WIDTH, SCREEN_HEIGHT); + // tft.setSPISpeed(SPI_SPEED); + // tft.setRotation(ROTATION); +} + + diff --git a/examples/RotatedRectangleTest/RotatedRectangleTest.ino b/examples/RotatedRectangleTest/RotatedRectangleTest.ino deleted file mode 100644 index aa226eb5..00000000 --- a/examples/RotatedRectangleTest/RotatedRectangleTest.ino +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include - -#define TFT_RST D0 -#define TFT_DC D1 -#define TFT_CS D2 -#define TFT_BACKLIGHT D3 -#define SPI_SPEED 40000000 -#define ROTATION 1 - -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 128 - -#define SERIAL_SPEED 9600 - -Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST); -GFXcanvas16 canvas = GFXcanvas16(SCREEN_WIDTH, SCREEN_HEIGHT); - -int16_t angle = 0; - -void setup(void) -{ - Serial.begin(SERIAL_SPEED); - Serial.println("Start up."); - initializeTFT(); -} - -void loop() -{ - canvas.fillScreen(ST77XX_BLACK); - canvas.drawRotatedRectangle(44, 44, 40, 30, angle, 0xFFFF); - canvas.fillRotatedRectangle(84, 84, 40, 30, angle, ST77XX_GREEN); - tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); - ++angle %= 360; -} - -void initializeTFT(void) -{ - pinMode(TFT_BACKLIGHT, OUTPUT); - digitalWrite(TFT_BACKLIGHT, HIGH); - tft.init(SCREEN_WIDTH, SCREEN_HEIGHT); - tft.setSPISpeed(SPI_SPEED); - tft.setRotation(ROTATION); - tft.fillScreen(ST77XX_BLACK); - tft.setCursor(0, 0); - tft.setTextColor(ST77XX_WHITE); - tft.setTextSize(1); - - Serial.println("TFT initialized."); - tft.println("TFT initialized."); -} From 28c426cda8e79717b89a295d2efe30459e48058d Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Sun, 9 Nov 2025 10:27:41 -0500 Subject: [PATCH 08/14] Updated naming for consistency and example file (formatting) --- Adafruit_GFX.cpp | 12 ++++++------ Adafruit_GFX.h | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index 680f787c..fcf1620a 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -711,9 +711,9 @@ void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, @param color 16-bit 5-6-5 Color to fill/draw with */ /**************************************************************************/ -void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, - int16_t w, int16_t h, - int16_t angleDeg, uint16_t color) { +void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, + int16_t h, int16_t angleDeg, + uint16_t color) { int16_t halfW = w / 2; int16_t halfH = h / 2; @@ -749,9 +749,9 @@ void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, @param color 16-bit 5-6-5 Color to fill/draw with */ /**************************************************************************/ -void Adafruit_GFX::fillRotatedRect(int16_t cenX, int16_t cenY, - int16_t w, int16_t h, - int16_t angleDeg, uint16_t color) { +void Adafruit_GFX::fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, + int16_t h, int16_t angleDeg, + uint16_t color) { int16_t halfW = w / 2; int16_t halfH = h / 2; diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index 53e8bd43..c125eae2 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -85,10 +85,10 @@ class Adafruit_GFX : public Print { int16_t radius, uint16_t color); void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color); - void drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, - int16_t h, int16_t angleDeg, uint16_t color); - void fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, - int16_t h, int16_t angleDeg, uint16_t color); + void drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w,int16_t h, + int16_t angleDeg, uint16_t color); + void fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w,int16_t h, + int16_t angleDeg, uint16_t color); void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, int16_t angleDeg); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, From 7c4191671c79c4d5cc05c2e4c8a3dcf9097df385 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Sun, 9 Nov 2025 10:58:30 -0500 Subject: [PATCH 09/14] Updated naming for consistency and example file (formatting) --- Adafruit_GFX.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index c125eae2..f6544b51 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -85,9 +85,9 @@ class Adafruit_GFX : public Print { int16_t radius, uint16_t color); void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color); - void drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w,int16_t h, + void drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color); - void fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w,int16_t h, + void fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color); void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, int16_t angleDeg); From 386cccc5e47ed758c568d307a5661580db581038 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Mon, 17 Nov 2025 15:05:33 -0500 Subject: [PATCH 10/14] Correct example --- examples/RotatedRectTest/RotatedRectTest.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/RotatedRectTest/RotatedRectTest.ino b/examples/RotatedRectTest/RotatedRectTest.ino index 2abf6522..6610cc91 100644 --- a/examples/RotatedRectTest/RotatedRectTest.ino +++ b/examples/RotatedRectTest/RotatedRectTest.ino @@ -22,10 +22,10 @@ #define SERIAL_SPEED 9600 -#define DRAW_CIRCLE_TOP 44 -#define DRAW_CIRCLE_LEFT 44 -#define FILL_CIRCLE_TOP 84 -#define FILL_CIRCLE_LEFT 84 +#define DRAW_CIRCLE_X 44 +#define DRAW_CIRCLE_Y 44 +#define FILL_CIRCLE_X 84 +#define FILL_CIRCLE_Y 84 #define WIDTH 40 #define HEIGHT 30 #define BLACK 0x0000 @@ -48,8 +48,8 @@ void setup(void) void loop() { canvas.fillScreen(BLACK); - canvas.drawRotatedRect(DRAW_CIRCLE_TOP, DRAW_CIRCLE_TOP, WIDTH, HEIGHT, angle, WHITE); - canvas.fillRotatedRect(DRAW_CIRCLE_TOP, DRAW_CIRCLE_TOP, WIDTH, HEIGHT, angle, GREEN); + canvas.drawRotatedRect(DRAW_CIRCLE_X, DRAW_CIRCLE_Y, WIDTH, HEIGHT, angle, WHITE); + canvas.fillRotatedRect(FILL_CIRCLE_X, FILL_CIRCLE_Y, WIDTH, HEIGHT, angle, GREEN); //Un-comment to display the rotated rectangles on your display //tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); ++angle %= 360; From 94b27863c4ca17210259500643eb17760cf80003 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Thu, 20 Nov 2025 15:01:23 -0500 Subject: [PATCH 11/14] Updated to properly handle even values for width and height. Simplified rotation. --- Adafruit_GFX.cpp | 129 +++++++++++-------- Adafruit_GFX.h | 3 +- examples/RotatedRectTest/RotatedRectTest.ino | 26 +++- 3 files changed, 100 insertions(+), 58 deletions(-) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index fcf1620a..961446fa 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -715,27 +715,43 @@ void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color) { - int16_t halfW = w / 2; - int16_t halfH = h / 2; - - int16_t x0 = cenX - halfW; // top-left - int16_t y0 = cenY - halfH; // top-left - int16_t x1 = cenX + halfW; // top-right - int16_t y1 = cenY - halfH; // top-right - int16_t x2 = cenX - halfW; // bottom-left - int16_t y2 = cenY + halfH; // bottom-left - int16_t x3 = cenX + halfW; // bottom-right - int16_t y3 = cenY + halfH; // bottom-right - - rotatePoint(x0, y0, cenX, cenY, angleDeg); - rotatePoint(x1, y1, cenX, cenY, angleDeg); - rotatePoint(x2, y2, cenX, cenY, angleDeg); - rotatePoint(x3, y3, cenX, cenY, angleDeg); - - drawLine(x0, y0, x1, y1, color); // top left to top right - drawLine(x0, y0, x2, y2, color); // top left to bottom left - drawLine(x1, y1, x3, y3, color); // top right to bottom right - drawLine(x2, y2, x3, y3, color); // bottom left to bottom right + if (w < 1 || h < 1) return; // We don't draw zero dimensioned objects + + int16_t W = w - 1; + int16_t H = h - 1; + + int16_t halfW = (W / 2); // Midpoint should always be integer + int16_t halfH = (H / 2); // Midpoint should always be integer + + int16_t x0 = W - halfW; // bottom-right + int16_t y0 = H - halfH; // bottom-right + int16_t x1 = -halfW; // bottom-left + int16_t y1 = H - halfH; // bottom-left + int16_t x2 = -halfW; // top-left + int16_t y2 = -halfH; // top-left + int16_t x3 = W - halfW; // top-right + int16_t y3 = -halfH; // top-right + + rotatePoint(x0, y0, angleDeg); + rotatePoint(x1, y1, angleDeg); + rotatePoint(x2, y2, angleDeg); + rotatePoint(x3, y3, angleDeg); + + x0 += cenX; + x1 += cenX; + x2 += cenX; + x3 += cenX; + + y0 += cenY; + y1 += cenY; + y2 += cenY; + y3 += cenY; + + + drawLine(x0, y0, x1, y1, color); // bottom right to bottom left + drawLine(x1, y1, x2, y2, color); // bottom left to top left + drawLine(x2, y2, x3, y3, color); // top left to top right + drawLine(x3, y3, x0, y0, color); // top right to bottom right } /**************************************************************************/ @@ -753,56 +769,63 @@ void Adafruit_GFX::fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color) { - int16_t halfW = w / 2; - int16_t halfH = h / 2; - - int16_t x0 = cenX - halfW; // top-left - int16_t y0 = cenY - halfH; // top-left - int16_t x1 = cenX + halfW; // top-right - int16_t y1 = cenY - halfH; // top-right - int16_t x2 = cenX - halfW; // bottom-left - int16_t y2 = cenY + halfH; // bottom-left - int16_t x3 = cenX + halfW; // bottom-right - int16_t y3 = cenY + halfH; // bottom-right - - rotatePoint(x0, y0, cenX, cenY, angleDeg); - rotatePoint(x1, y1, cenX, cenY, angleDeg); - rotatePoint(x2, y2, cenX, cenY, angleDeg); - rotatePoint(x3, y3, cenX, cenY, angleDeg); + if (w < 1 || h < 1) return; // We don't draw zero dimensioned objects + + int16_t W = w - 1; + int16_t H = h - 1; + + int16_t halfW = (W / 2); // Midpoint should always be integer + int16_t halfH = (H / 2); // Midpoint should always be integer + + int16_t x0 = W - halfW; // bottom-right + int16_t y0 = H - halfH; // bottom-right + int16_t x1 = -halfW; // bottom-left + int16_t y1 = H - halfH; // bottom-left + int16_t x2 = -halfW; // top-left + int16_t y2 = -halfH; // top-left + int16_t x3 = W - halfW; // top-right + int16_t y3 = -halfH; // top-right + + rotatePoint(x0, y0, angleDeg); + rotatePoint(x1, y1, angleDeg); + rotatePoint(x2, y2, angleDeg); + rotatePoint(x3, y3, angleDeg); + + x0 += cenX; + x1 += cenX; + x2 += cenX; + x3 += cenX; + + y0 += cenY; + y1 += cenY; + y2 += cenY; + y3 += cenY; fillTriangle(x0, y0, x1, y1, x2, y2, color); - fillTriangle(x1, y1, x2, y2, x3, y3, color); + fillTriangle(x2, y2, x3, y3, x0, y0, color); } /**************************************************************************/ /*! - @brief Rotate a point around another point + @brief Rotate a point in standard position @param x0 x coordinate of point to rotate. This is passed by reference and updated upon return @param y0 y coordinate of point to rotate. This is passed by reference and updated upon return - @param orgX x coordinate of point to be rotated around - @param orgY y coordinate of point to be rotated around @param angleDeg angle of rotation of rectangle */ /**************************************************************************/ -void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, - int16_t orgY, int16_t angleDeg) { +void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t angleDeg) { float angleRad = radians(angleDeg); float s = sin(angleRad); float c = cos(angleRad); - - // Translate to standard position - int16_t xStan = x0 - orgX; - int16_t yStan = y0 - orgY; + + float x = x0; + float y = y0; // Rotate point - int16_t xRot = (int16_t)((float)xStan * c - (float)yStan * s); - int16_t yRot = (int16_t)((float)xStan * s + (float)yStan * c); - - // Translate back - x0 = xRot + orgX; - y0 = yRot + orgY; + x0 = (int16_t)((x * c) - (y * s)); + y0 = (int16_t)((x * s) + (y * c)); } /**************************************************************************/ diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index f6544b51..dd9dc0dc 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -89,8 +89,7 @@ class Adafruit_GFX : public Print { int16_t angleDeg, uint16_t color); void fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color); - void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, - int16_t angleDeg); + void rotatePoint(int16_t &x0, int16_t &y0, int16_t angleDeg); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, diff --git a/examples/RotatedRectTest/RotatedRectTest.ino b/examples/RotatedRectTest/RotatedRectTest.ino index 6610cc91..20763919 100644 --- a/examples/RotatedRectTest/RotatedRectTest.ino +++ b/examples/RotatedRectTest/RotatedRectTest.ino @@ -48,11 +48,31 @@ void setup(void) void loop() { canvas.fillScreen(BLACK); - canvas.drawRotatedRect(DRAW_CIRCLE_X, DRAW_CIRCLE_Y, WIDTH, HEIGHT, angle, WHITE); - canvas.fillRotatedRect(FILL_CIRCLE_X, FILL_CIRCLE_Y, WIDTH, HEIGHT, angle, GREEN); + canvas.fillRect(0, 10, 10, 1, GREEN); + canvas.fillRotatedRect(14, 10, 10, 1, angle, GREEN); + canvas.fillRect(20, 10, 10, 2, GREEN); + canvas.fillRotatedRect(34, 10, 10, 2, angle, GREEN); + canvas.fillRect(40, 10, 10, 3, GREEN); + canvas.fillRotatedRect(54, 11, 10, 3, angle, GREEN); + canvas.fillRect(60, 10, 10, 4, GREEN); + canvas.fillRotatedRect(74, 11, 10, 4, angle, GREEN); + canvas.fillRect(80, 10, 10, 5, GREEN); + canvas.fillRotatedRect(94, 12, 10, 5, angle, GREEN); //Un-comment to display the rotated rectangles on your display //tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); - ++angle %= 360; + delay(10000); + + for( int scale = 0; scale < HEIGHT; scale++) + { + for(int angle = 0; angle < 360; angle++) + { + canvas.fillScreen(BLACK); + canvas.drawRotatedRect(DRAW_CIRCLE_X, DRAW_CIRCLE_Y, WIDTH - scale, HEIGHT - scale, angle, WHITE); + canvas.fillRotatedRect(FILL_CIRCLE_X, FILL_CIRCLE_Y, WIDTH - scale, HEIGHT - scale, angle, GREEN); + //Un-comment to display the rotated rectangles on your display + //tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); + } + } } void initializeTFT(void) From 0fa8fa0c4b50ff86b530b376574bdbca1a46e5b8 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Thu, 20 Nov 2025 15:01:23 -0500 Subject: [PATCH 12/14] Updated to handle even values for width and height. --- Adafruit_GFX.cpp | 129 +++++++++++-------- Adafruit_GFX.h | 3 +- examples/RotatedRectTest/RotatedRectTest.ino | 26 +++- 3 files changed, 100 insertions(+), 58 deletions(-) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index fcf1620a..961446fa 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -715,27 +715,43 @@ void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color) { - int16_t halfW = w / 2; - int16_t halfH = h / 2; - - int16_t x0 = cenX - halfW; // top-left - int16_t y0 = cenY - halfH; // top-left - int16_t x1 = cenX + halfW; // top-right - int16_t y1 = cenY - halfH; // top-right - int16_t x2 = cenX - halfW; // bottom-left - int16_t y2 = cenY + halfH; // bottom-left - int16_t x3 = cenX + halfW; // bottom-right - int16_t y3 = cenY + halfH; // bottom-right - - rotatePoint(x0, y0, cenX, cenY, angleDeg); - rotatePoint(x1, y1, cenX, cenY, angleDeg); - rotatePoint(x2, y2, cenX, cenY, angleDeg); - rotatePoint(x3, y3, cenX, cenY, angleDeg); - - drawLine(x0, y0, x1, y1, color); // top left to top right - drawLine(x0, y0, x2, y2, color); // top left to bottom left - drawLine(x1, y1, x3, y3, color); // top right to bottom right - drawLine(x2, y2, x3, y3, color); // bottom left to bottom right + if (w < 1 || h < 1) return; // We don't draw zero dimensioned objects + + int16_t W = w - 1; + int16_t H = h - 1; + + int16_t halfW = (W / 2); // Midpoint should always be integer + int16_t halfH = (H / 2); // Midpoint should always be integer + + int16_t x0 = W - halfW; // bottom-right + int16_t y0 = H - halfH; // bottom-right + int16_t x1 = -halfW; // bottom-left + int16_t y1 = H - halfH; // bottom-left + int16_t x2 = -halfW; // top-left + int16_t y2 = -halfH; // top-left + int16_t x3 = W - halfW; // top-right + int16_t y3 = -halfH; // top-right + + rotatePoint(x0, y0, angleDeg); + rotatePoint(x1, y1, angleDeg); + rotatePoint(x2, y2, angleDeg); + rotatePoint(x3, y3, angleDeg); + + x0 += cenX; + x1 += cenX; + x2 += cenX; + x3 += cenX; + + y0 += cenY; + y1 += cenY; + y2 += cenY; + y3 += cenY; + + + drawLine(x0, y0, x1, y1, color); // bottom right to bottom left + drawLine(x1, y1, x2, y2, color); // bottom left to top left + drawLine(x2, y2, x3, y3, color); // top left to top right + drawLine(x3, y3, x0, y0, color); // top right to bottom right } /**************************************************************************/ @@ -753,56 +769,63 @@ void Adafruit_GFX::fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color) { - int16_t halfW = w / 2; - int16_t halfH = h / 2; - - int16_t x0 = cenX - halfW; // top-left - int16_t y0 = cenY - halfH; // top-left - int16_t x1 = cenX + halfW; // top-right - int16_t y1 = cenY - halfH; // top-right - int16_t x2 = cenX - halfW; // bottom-left - int16_t y2 = cenY + halfH; // bottom-left - int16_t x3 = cenX + halfW; // bottom-right - int16_t y3 = cenY + halfH; // bottom-right - - rotatePoint(x0, y0, cenX, cenY, angleDeg); - rotatePoint(x1, y1, cenX, cenY, angleDeg); - rotatePoint(x2, y2, cenX, cenY, angleDeg); - rotatePoint(x3, y3, cenX, cenY, angleDeg); + if (w < 1 || h < 1) return; // We don't draw zero dimensioned objects + + int16_t W = w - 1; + int16_t H = h - 1; + + int16_t halfW = (W / 2); // Midpoint should always be integer + int16_t halfH = (H / 2); // Midpoint should always be integer + + int16_t x0 = W - halfW; // bottom-right + int16_t y0 = H - halfH; // bottom-right + int16_t x1 = -halfW; // bottom-left + int16_t y1 = H - halfH; // bottom-left + int16_t x2 = -halfW; // top-left + int16_t y2 = -halfH; // top-left + int16_t x3 = W - halfW; // top-right + int16_t y3 = -halfH; // top-right + + rotatePoint(x0, y0, angleDeg); + rotatePoint(x1, y1, angleDeg); + rotatePoint(x2, y2, angleDeg); + rotatePoint(x3, y3, angleDeg); + + x0 += cenX; + x1 += cenX; + x2 += cenX; + x3 += cenX; + + y0 += cenY; + y1 += cenY; + y2 += cenY; + y3 += cenY; fillTriangle(x0, y0, x1, y1, x2, y2, color); - fillTriangle(x1, y1, x2, y2, x3, y3, color); + fillTriangle(x2, y2, x3, y3, x0, y0, color); } /**************************************************************************/ /*! - @brief Rotate a point around another point + @brief Rotate a point in standard position @param x0 x coordinate of point to rotate. This is passed by reference and updated upon return @param y0 y coordinate of point to rotate. This is passed by reference and updated upon return - @param orgX x coordinate of point to be rotated around - @param orgY y coordinate of point to be rotated around @param angleDeg angle of rotation of rectangle */ /**************************************************************************/ -void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, - int16_t orgY, int16_t angleDeg) { +void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t angleDeg) { float angleRad = radians(angleDeg); float s = sin(angleRad); float c = cos(angleRad); - - // Translate to standard position - int16_t xStan = x0 - orgX; - int16_t yStan = y0 - orgY; + + float x = x0; + float y = y0; // Rotate point - int16_t xRot = (int16_t)((float)xStan * c - (float)yStan * s); - int16_t yRot = (int16_t)((float)xStan * s + (float)yStan * c); - - // Translate back - x0 = xRot + orgX; - y0 = yRot + orgY; + x0 = (int16_t)((x * c) - (y * s)); + y0 = (int16_t)((x * s) + (y * c)); } /**************************************************************************/ diff --git a/Adafruit_GFX.h b/Adafruit_GFX.h index f6544b51..dd9dc0dc 100644 --- a/Adafruit_GFX.h +++ b/Adafruit_GFX.h @@ -89,8 +89,7 @@ class Adafruit_GFX : public Print { int16_t angleDeg, uint16_t color); void fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color); - void rotatePoint(int16_t &x0, int16_t &y0, int16_t orgX, int16_t orgY, - int16_t angleDeg); + void rotatePoint(int16_t &x0, int16_t &y0, int16_t angleDeg); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color); void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, diff --git a/examples/RotatedRectTest/RotatedRectTest.ino b/examples/RotatedRectTest/RotatedRectTest.ino index 6610cc91..20763919 100644 --- a/examples/RotatedRectTest/RotatedRectTest.ino +++ b/examples/RotatedRectTest/RotatedRectTest.ino @@ -48,11 +48,31 @@ void setup(void) void loop() { canvas.fillScreen(BLACK); - canvas.drawRotatedRect(DRAW_CIRCLE_X, DRAW_CIRCLE_Y, WIDTH, HEIGHT, angle, WHITE); - canvas.fillRotatedRect(FILL_CIRCLE_X, FILL_CIRCLE_Y, WIDTH, HEIGHT, angle, GREEN); + canvas.fillRect(0, 10, 10, 1, GREEN); + canvas.fillRotatedRect(14, 10, 10, 1, angle, GREEN); + canvas.fillRect(20, 10, 10, 2, GREEN); + canvas.fillRotatedRect(34, 10, 10, 2, angle, GREEN); + canvas.fillRect(40, 10, 10, 3, GREEN); + canvas.fillRotatedRect(54, 11, 10, 3, angle, GREEN); + canvas.fillRect(60, 10, 10, 4, GREEN); + canvas.fillRotatedRect(74, 11, 10, 4, angle, GREEN); + canvas.fillRect(80, 10, 10, 5, GREEN); + canvas.fillRotatedRect(94, 12, 10, 5, angle, GREEN); //Un-comment to display the rotated rectangles on your display //tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); - ++angle %= 360; + delay(10000); + + for( int scale = 0; scale < HEIGHT; scale++) + { + for(int angle = 0; angle < 360; angle++) + { + canvas.fillScreen(BLACK); + canvas.drawRotatedRect(DRAW_CIRCLE_X, DRAW_CIRCLE_Y, WIDTH - scale, HEIGHT - scale, angle, WHITE); + canvas.fillRotatedRect(FILL_CIRCLE_X, FILL_CIRCLE_Y, WIDTH - scale, HEIGHT - scale, angle, GREEN); + //Un-comment to display the rotated rectangles on your display + //tft.drawRGBBitmap(0, 0, canvas.getBuffer(), SCREEN_WIDTH, SCREEN_HEIGHT); + } + } } void initializeTFT(void) From 06a55c1754d2591e6d0425c0078f21de8ada6d40 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Thu, 20 Nov 2025 15:20:32 -0500 Subject: [PATCH 13/14] Updated to handle even values for width and height From 16f6dc8b7d348d708f6eccfe1964bb0612a01907 Mon Sep 17 00:00:00 2001 From: Bill Merryman Date: Thu, 20 Nov 2025 15:35:03 -0500 Subject: [PATCH 14/14] formatting --- Adafruit_GFX.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Adafruit_GFX.cpp b/Adafruit_GFX.cpp index 961446fa..33eaff06 100644 --- a/Adafruit_GFX.cpp +++ b/Adafruit_GFX.cpp @@ -715,11 +715,12 @@ void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color) { - if (w < 1 || h < 1) return; // We don't draw zero dimensioned objects + if (w < 1 || h < 1) + return; // We don't draw zero dimensioned objects int16_t W = w - 1; int16_t H = h - 1; - + int16_t halfW = (W / 2); // Midpoint should always be integer int16_t halfH = (H / 2); // Midpoint should always be integer @@ -736,17 +737,16 @@ void Adafruit_GFX::drawRotatedRect(int16_t cenX, int16_t cenY, int16_t w, rotatePoint(x1, y1, angleDeg); rotatePoint(x2, y2, angleDeg); rotatePoint(x3, y3, angleDeg); - + x0 += cenX; x1 += cenX; x2 += cenX; x3 += cenX; - + y0 += cenY; y1 += cenY; y2 += cenY; y3 += cenY; - drawLine(x0, y0, x1, y1, color); // bottom right to bottom left drawLine(x1, y1, x2, y2, color); // bottom left to top left @@ -769,11 +769,12 @@ void Adafruit_GFX::fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, int16_t h, int16_t angleDeg, uint16_t color) { - if (w < 1 || h < 1) return; // We don't draw zero dimensioned objects + if (w < 1 || h < 1) + return; // We don't draw zero dimensioned objects int16_t W = w - 1; int16_t H = h - 1; - + int16_t halfW = (W / 2); // Midpoint should always be integer int16_t halfH = (H / 2); // Midpoint should always be integer @@ -790,12 +791,12 @@ void Adafruit_GFX::fillRotatedRect(int16_t cenX, int16_t cenY, int16_t w, rotatePoint(x1, y1, angleDeg); rotatePoint(x2, y2, angleDeg); rotatePoint(x3, y3, angleDeg); - + x0 += cenX; x1 += cenX; x2 += cenX; x3 += cenX; - + y0 += cenY; y1 += cenY; y2 += cenY; @@ -819,7 +820,7 @@ void Adafruit_GFX::rotatePoint(int16_t &x0, int16_t &y0, int16_t angleDeg) { float angleRad = radians(angleDeg); float s = sin(angleRad); float c = cos(angleRad); - + float x = x0; float y = y0;