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
129 changes: 129 additions & 0 deletions Adafruit_GFX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,135 @@ 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 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::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

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
}

/**************************************************************************/
/*!
@brief Draw a filled rotated rectangle
@param cenX x coordinate of center of rectangle
@param cenY y coordinate of center 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::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

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(x2, y2, x3, y3, x0, y0, color);
}

/**************************************************************************/
/*!
@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 angleDeg angle of rotation of rectangle
*/
/**************************************************************************/
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;

// Rotate point
x0 = (int16_t)((x * c) - (y * s));
y0 = (int16_t)((x * s) + (y * c));
}

/**************************************************************************/
/*!
@brief Draw a triangle with no fill color
Expand Down
5 changes: 5 additions & 0 deletions Adafruit_GFX.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ 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 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,
Expand Down
87 changes: 87 additions & 0 deletions examples/RotatedRectTest/RotatedRectTest.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/***************************************************
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 <SPI.h>
// #include <Adafruit_ST7789.h>
#include <Adafruit_GFX.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 128
#define SCREEN_HEIGHT 128

#define SERIAL_SPEED 9600

#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
#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.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);
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)
{
// pinMode(TFT_BACKLIGHT, OUTPUT);
// digitalWrite(TFT_BACKLIGHT, HIGH);
// tft.init(SCREEN_WIDTH, SCREEN_HEIGHT);
// tft.setSPISpeed(SPI_SPEED);
// tft.setRotation(ROTATION);
}