Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions Adafruit_GFX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
int16_t halfH = height / 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
}

/**************************************************************************/
/*!
@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;
int16_t halfH = height / 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);

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 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) {
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
Expand Down
6 changes: 6 additions & 0 deletions Adafruit_GFX.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +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 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,
Expand Down
52 changes: 52 additions & 0 deletions examples/RotatedRectangleTest/RotatedRectangleTest.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>

#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 320
#define SCREEN_HEIGHT 240

#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.");
}
Loading