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
138 changes: 138 additions & 0 deletions Adafruit_GFX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ POSSIBILITY OF SUCH DAMAGE.

#include "Adafruit_GFX.h"
#include "glcdfont.c"
#include <math.h>
#define PI 3.1415926
#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
Expand Down Expand Up @@ -368,6 +370,141 @@ void Adafruit_GFX::fillRoundRect(int16_t x, int16_t y, int16_t w,
endWrite();
}

// Draw a Pentagram (five-pointed star outline)
// (x0, y0): center position, r0: outer radius
void Adafruit_GFX::drawPentagram(int16_t x0, int16_t y0,
int16_t r0, uint16_t color) {
int16_t xa, ya, xb, yb, xc, yc, xd, yd, xe, ye;

// Calculate 5 vertices of the pentagram
xa = x0;
ya = y0 - r0;
xb = x0 - r0 * sin(PI / 180 * 72);
yb = y0 - r0 * cos(PI / 180 * 72);
xc = x0 - r0 * sin(PI / 180 * 36);
yc = y0 + r0 * cos(PI / 180 * 36);
xd = x0 + r0 * sin(PI / 180 * 36);
yd = y0 + r0 * cos(PI / 180 * 36);
xe = x0 + r0 * sin(PI / 180 * 72);
ye = y0 - r0 * cos(PI / 180 * 72);

// Draw the 5 lines connecting every other vertex
drawLine(xa, ya, xc, yc, color);
drawLine(xc, yc, xe, ye, color);
drawLine(xe, ye, xb, yb, color);
drawLine(xb, yb, xd, yd, color);
drawLine(xd, yd, xa, ya, color);
}

// Fill a Pentagram (five-pointed star)
void Adafruit_GFX::fillPentagram(int16_t x0, int16_t y0,
int16_t r0, uint16_t color) {
int16_t xa, ya, xb, yb, xc, yc, xd, yd, xe, ye;

// Calculate 5 outer vertices
xa = x0;
ya = y0 - r0;
xb = x0 - r0 * sin(PI / 180 * 72);
yb = y0 - r0 * cos(PI / 180 * 72);
xc = x0 - r0 * sin(PI / 180 * 36);
yc = y0 + r0 * cos(PI / 180 * 36);
xd = x0 + r0 * sin(PI / 180 * 36);
yd = y0 + r0 * cos(PI / 180 * 36);
xe = x0 + r0 * sin(PI / 180 * 72);
ye = y0 - r0 * cos(PI / 180 * 72);

// Fill the pentagram using 5 triangles from center
fillTriangle(x0, y0, xa, ya, xc, yc, color);
fillTriangle(x0, y0, xc, yc, xe, ye, color);
fillTriangle(x0, y0, xe, ye, xb, yb, color);
fillTriangle(x0, y0, xb, yb, xd, yd, color);
fillTriangle(x0, y0, xd, yd, xa, ya, color);

// Draw outline
drawPentagram(x0, y0, r0, color);
}

// Draw an ellipse outline using midpoint algorithm
// (x0, y0): center position, rx: horizontal radius, ry: vertical radius
void Adafruit_GFX::drawEllipse(int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint16_t color) {
if (rx < 1 || ry < 1) return;

int16_t x, y;
int32_t rx2 = (int32_t)rx * rx;
int32_t ry2 = (int32_t)ry * ry;
int32_t fx2 = 4 * rx2;
int32_t fy2 = 4 * ry2;
int32_t s;

startWrite();

// Region 1
for (x = 0, y = ry, s = 2*ry2 + rx2*(1-2*ry); ry2*x <= rx2*y; x++) {
writePixel(x0 + x, y0 + y, color);
writePixel(x0 - x, y0 + y, color);
writePixel(x0 + x, y0 - y, color);
writePixel(x0 - x, y0 - y, color);
if (s >= 0) {
s += fx2 * (1 - y);
y--;
}
s += ry2 * ((4 * x) + 6);
}

// Region 2
for (x = rx, y = 0, s = 2*rx2 + ry2*(1-2*rx); rx2*y <= ry2*x; y++) {
writePixel(x0 + x, y0 + y, color);
writePixel(x0 - x, y0 + y, color);
writePixel(x0 + x, y0 - y, color);
writePixel(x0 - x, y0 - y, color);
if (s >= 0) {
s += fy2 * (1 - x);
x--;
}
s += rx2 * ((4 * y) + 6);
}

endWrite();
}

// Fill an ellipse using midpoint algorithm
void Adafruit_GFX::fillEllipse(int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint16_t color) {
if (rx < 1 || ry < 1) return;

int16_t x, y;
int32_t rx2 = (int32_t)rx * rx;
int32_t ry2 = (int32_t)ry * ry;
int32_t fx2 = 4 * rx2;
int32_t fy2 = 4 * ry2;
int32_t s;

startWrite();

// Draw horizontal lines for the filled ellipse
for (x = 0, y = ry, s = 2*ry2 + rx2*(1-2*ry); ry2*x <= rx2*y; x++) {
writeFastHLine(x0 - x, y0 - y, 2 * x + 1, color);
writeFastHLine(x0 - x, y0 + y, 2 * x + 1, color);
if (s >= 0) {
s += fx2 * (1 - y);
y--;
}
s += ry2 * ((4 * x) + 6);
}

for (x = rx, y = 0, s = 2*rx2 + ry2*(1-2*rx); rx2*y <= ry2*x; y++) {
writeFastHLine(x0 - x, y0 - y, 2 * x + 1, color);
writeFastHLine(x0 - x, y0 + y, 2 * x + 1, color);
if (s >= 0) {
s += fy2 * (1 - x);
x--;
}
s += rx2 * ((4 * y) + 6);
}

endWrite();
}


// Draw a triangle
void Adafruit_GFX::drawTriangle(int16_t x0, int16_t y0,
int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) {
Expand Down Expand Up @@ -1346,3 +1483,4 @@ void GFXcanvas16::fillScreen(uint16_t color) {
}
}


6 changes: 5 additions & 1 deletion Adafruit_GFX.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ class Adafruit_GFX : public Print {
// Optional and probably not necessary to change
drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color),
drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);

// These exist only with Adafruit_GFX (no subclass overrides)
void
drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
Expand All @@ -56,6 +55,10 @@ class Adafruit_GFX : public Print {
fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color),
fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername,
int16_t delta, uint16_t color),
drawPentagram(int16_t x0, int16_t y0, int16_t r0, uint16_t color),
fillPentagram(int16_t x0, int16_t y0, int16_t r0, uint16_t color),
drawEllipse(int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint16_t color),
fillEllipse(int16_t x0, int16_t y0, int16_t rx, int16_t ry, uint16_t color),
drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
int16_t x2, int16_t y2, uint16_t color),
fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
Expand Down Expand Up @@ -209,3 +212,4 @@ class GFXcanvas16 : public Adafruit_GFX {
};

#endif // _ADAFRUIT_GFX_H

135 changes: 135 additions & 0 deletions examples/gfx_test/gfx_test.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
GFX Library Test - 测试新增的绘图方法
drawPentagram(), fillPentagram(), drawEllipse(), fillEllipse()

硬件连接 (Arduino UNO + SSD1306 OLED SPI 7针):
- GND -> GND
- VCC -> 5V
- D0/SCLK -> D13
- D1/MOSI -> D11
- RES/RST -> D8
- DC -> D7
- CS -> D9
*/

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_DC 7
#define OLED_RST 8
#define OLED_CS 9

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, OLED_DC, OLED_RST, OLED_CS);

void setup() {
Serial.begin(115200);
delay(500);
Serial.println(F("===== GFX Test 启动 ====="));
Serial.println(F("[OLED] 开始初始化 display.begin() ..."));

if(!display.begin(SSD1306_SWITCHCAPVCC)) {
Serial.println(F("[OLED] 初始化失败!请检查:"));
Serial.println(F(" 1) VCC/GND 是否接反"));
Serial.println(F(" 2) 电压是否正确(3.3V 还是 5V)"));
Serial.println(F(" 3) D0->D13, D1->D11, RST->D8, DC->D7, CS->D9"));
Serial.println(F(" 4) 屏幕芯片是否真的是 SSD1306"));
for(;;);
}

Serial.println(F("[OLED] 初始化成功!"));

display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("GFX Test Start"));
display.display();

Serial.println(F("[OLED] 已显示 'GFX Test Start'"));
delay(2000);
}

void loop() {
Serial.println(F("[Loop] 开始测试 drawPentagram"));
testDrawPentagram();
delay(2000);

Serial.println(F("[Loop] 开始测试 fillPentagram"));
testFillPentagram();
delay(2000);

Serial.println(F("[Loop] 开始测试 drawEllipse"));
testDrawEllipse();
delay(2000);

Serial.println(F("[Loop] 开始测试 fillEllipse"));
testFillEllipse();
delay(2000);

Serial.println(F("[Loop] 开始测试 All Shapes"));
testAllShapes();
delay(3000);

Serial.println(F("[Loop] 一轮测试完成\n"));
}

void testDrawPentagram() {
Serial.println(F(" 清屏..."));
display.clearDisplay();
display.setCursor(0, 0);
display.println(F("drawPentagram()"));

Serial.println(F(" 绘制五角星..."));
display.drawPentagram(64, 40, 20, SSD1306_WHITE);

Serial.println(F(" 刷新显示..."));
display.display();
Serial.println(F(" 完成"));
}

void testFillPentagram() {
display.clearDisplay();
display.setCursor(0, 0);
display.println(F("fillPentagram()"));

display.fillPentagram(64, 40, 20, SSD1306_WHITE);

display.display();
}

void testDrawEllipse() {
display.clearDisplay();
display.setCursor(0, 0);
display.println(F("drawEllipse()"));

display.drawEllipse(64, 36, 40, 20, SSD1306_WHITE);
display.drawEllipse(64, 36, 20, 25, SSD1306_WHITE);

display.display();
}

void testFillEllipse() {
display.clearDisplay();
display.setCursor(0, 0);
display.println(F("fillEllipse()"));

display.fillEllipse(64, 40, 35, 18, SSD1306_WHITE);

display.display();
}

void testAllShapes() {
display.clearDisplay();
display.setCursor(0, 0);
display.println(F("All Shapes"));

display.drawPentagram(25, 40, 15, SSD1306_WHITE);
display.drawEllipse(70, 40, 25, 15, SSD1306_WHITE);
display.fillEllipse(110, 40, 12, 18, SSD1306_WHITE);

display.display();
}

69 changes: 69 additions & 0 deletions examples/simple_test/simple_test.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 最简单的测试 - 只画一个像素点
// 接线:GND->GND, VCC->5V, D0->D13, D1->D11, RES->D8, DC->D7, CS->D9

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_DC 7
#define OLED_RST 8
#define OLED_CS 9

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, OLED_DC, OLED_RST, OLED_CS);

void setup() {
Serial.begin(115200);
delay(500);
Serial.println(F("===== 简单测试 ====="));

if (!display.begin(SSD1306_SWITCHCAPVCC)) {
Serial.println(F("[错误] 初始化失败"));
while (1);
}

Serial.println(F("[成功] 初始化完成"));

// 测试1: 清屏
Serial.println(F("测试1: 清屏"));
display.clearDisplay();
display.display();
delay(1000);

// 测试2: 画一个像素点
Serial.println(F("测试2: 画像素点 (64, 32)"));
display.drawPixel(64, 32, SSD1306_WHITE);
display.display();
delay(1000);

// 测试3: 画一条线
Serial.println(F("测试3: 画线"));
display.clearDisplay();
display.drawLine(0, 0, 127, 63, SSD1306_WHITE);
display.display();
delay(1000);

// 测试4: 画矩形
Serial.println(F("测试4: 画矩形"));
display.clearDisplay();
display.drawRect(10, 10, 50, 30, SSD1306_WHITE);
display.display();
delay(1000);

// 测试5: 显示文字
Serial.println(F("测试5: 显示文字"));
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 20);
display.println(F("HELLO"));
display.display();

Serial.println(F("所有测试完成!"));
}

void loop() {
// 空
}