Skip to content

Commit d4b8234

Browse files
committed
Support triangles
Code provided by @mtsem. Fixes #329
1 parent fe63fb1 commit d4b8234

File tree

3 files changed

+105
-9
lines changed

3 files changed

+105
-9
lines changed

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Build Status](https://travis-ci.org/ThingPulse/esp8266-oled-ssd1306.svg?branch=master)](https://travis-ci.org/ThingPulse/esp8266-oled-ssd1306)
1+
[![Build Status](https://travis-ci.com/ThingPulse/esp8266-oled-ssd1306.svg?branch=master)](https://travis-ci.com/ThingPulse/esp8266-oled-ssd1306)
22

33
# ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS)
44

@@ -9,7 +9,7 @@ This library drives the OLED display included in the [ThingPulse IoT starter kit
99

1010
[![ThingPulse ESP8266 WeatherStation Classic Kit](https://github.com/ThingPulse/esp8266-weather-station/blob/master/resources/ThingPulse-ESP8266-Weather-Station.jpeg?raw=true)](https://thingpulse.com/product/esp8266-iot-electronics-starter-kit-weatherstation-planespotter-worldclock/)
1111

12-
You can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under "ESP8266 and ESP32 Oled Driver for SSD1306 display". For mbed-os a copy of the files are available as an mbed-os library.
12+
You can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under "ESP8266 and ESP32 Oled Driver for SSD1306 display". For mbed-os a copy of the files are available as an mbed-os library.
1313

1414
It is also available as a [PlatformIO library](https://platformio.org/lib/show/2978/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays/examples). Just execute the following command:
1515
```
@@ -71,7 +71,7 @@ The library supports different protocols to access the OLED display. Currently t
7171
### I2C with Wire.h
7272

7373
```C++
74-
#include <Wire.h>
74+
#include <Wire.h>
7575
#include "SSD1306Wire.h"
7676

7777
// for 128x64 displays:
@@ -87,7 +87,7 @@ SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
8787
8888
for a SH1106:
8989
```C++
90-
#include <Wire.h>
90+
#include <Wire.h>
9191
#include "SH1106Wire.h"
9292
9393
SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
@@ -205,6 +205,12 @@ void drawCircle(int16_t x, int16_t y, int16_t radius);
205205
// Fill circle
206206
void fillCircle(int16_t x, int16_t y, int16_t radius);
207207
208+
// Draw an empty triangle i.e. only the outline
209+
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
210+
211+
// Draw a solid triangle i.e. filled
212+
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
213+
208214
// Draw a line horizontally
209215
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
210216

src/OLEDDisplay.cpp

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ bool OLEDDisplay::allocateBuffer() {
9999
bool OLEDDisplay::init() {
100100

101101
BufferOffset = getBufferOffset();
102-
102+
103103
if(!allocateBuffer()) {
104104
return false;
105105
}
@@ -304,6 +304,90 @@ void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) {
304304

305305
}
306306

307+
void OLEDDisplay::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
308+
int16_t x2, int16_t y2) {
309+
drawLine(x0, y0, x1, y1);
310+
drawLine(x1, y1, x2, y2);
311+
drawLine(x2, y2, x0, y0);
312+
}
313+
314+
void OLEDDisplay::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
315+
int16_t x2, int16_t y2) {
316+
int16_t a, b, y, last;
317+
318+
if (y0 > y1) {
319+
_swap_int16_t(y0, y1);
320+
_swap_int16_t(x0, x1);
321+
}
322+
if (y1 > y2) {
323+
_swap_int16_t(y2, y1);
324+
_swap_int16_t(x2, x1);
325+
}
326+
if (y0 > y1) {
327+
_swap_int16_t(y0, y1);
328+
_swap_int16_t(x0, x1);
329+
}
330+
331+
if (y0 == y2) {
332+
a = b = x0;
333+
if (x1 < a) {
334+
a = x1;
335+
} else if (x1 > b) {
336+
b = x1;
337+
}
338+
if (x2 < a) {
339+
a = x2;
340+
} else if (x2 > b) {
341+
b = x2;
342+
}
343+
drawHorizontalLine(a, y0, b - a + 1);
344+
return;
345+
}
346+
347+
int16_t
348+
dx01 = x1 - x0,
349+
dy01 = y1 - y0,
350+
dx02 = x2 - x0,
351+
dy02 = y2 - y0,
352+
dx12 = x2 - x1,
353+
dy12 = y2 - y1;
354+
int32_t
355+
sa = 0,
356+
sb = 0;
357+
358+
if (y1 == y2) {
359+
last = y1; // Include y1 scanline
360+
} else {
361+
last = y1 - 1; // Skip it
362+
}
363+
364+
for (y = y0; y <= last; y++) {
365+
a = x0 + sa / dy01;
366+
b = x0 + sb / dy02;
367+
sa += dx01;
368+
sb += dx02;
369+
370+
if (a > b) {
371+
_swap_int16_t(a, b);
372+
}
373+
drawHorizontalLine(a, y, b - a + 1);
374+
}
375+
376+
sa = dx12 * (y - y1);
377+
sb = dx02 * (y - y0);
378+
for (; y <= y2; y++) {
379+
a = x1 + sa / dy12;
380+
b = x0 + sb / dy02;
381+
sa += dx12;
382+
sb += dx02;
383+
384+
if (a > b) {
385+
_swap_int16_t(a, b);
386+
}
387+
drawHorizontalLine(a, y, b - a + 1);
388+
}
389+
}
390+
307391
void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
308392
if (y < 0 || y >= this->height()) { return; }
309393

@@ -884,7 +968,7 @@ void OLEDDisplay::sendInitCommands(void) {
884968
sendCommand(SETDISPLAYOFFSET);
885969
sendCommand(0x00);
886970
if(geometry == GEOMETRY_64_32)
887-
sendCommand(0x00);
971+
sendCommand(0x00);
888972
else
889973
sendCommand(SETSTARTLINE);
890974
sendCommand(CHARGEPUMP);

src/OLEDDisplay.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ class OLEDDisplay : public Stream {
215215
// Fill circle
216216
void fillCircle(int16_t x, int16_t y, int16_t radius);
217217

218+
// Draw an empty triangle i.e. only the outline
219+
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
220+
221+
// Draw a solid triangle i.e. filled
222+
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
223+
218224
// Draw a line horizontally
219225
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
220226

@@ -320,7 +326,7 @@ class OLEDDisplay : public Stream {
320326
// Implement needed function to be compatible with Print class
321327
size_t write(uint8_t c);
322328
size_t write(const char* s);
323-
329+
324330
// Implement needed function to be compatible with Stream class
325331
#ifdef __MBED__
326332
int _putc(int c);
@@ -361,7 +367,7 @@ class OLEDDisplay : public Stream {
361367
// the header size of the buffer used, e.g. for the SPI command header
362368
int BufferOffset;
363369
virtual int getBufferOffset(void) = 0;
364-
370+
365371
// Send a command to the display (low level function)
366372
virtual void sendCommand(uint8_t com) {(void)com;};
367373

@@ -377,7 +383,7 @@ class OLEDDisplay : public Stream {
377383
void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline));
378384

379385
void drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth);
380-
386+
381387
FontTableLookupFunction fontTableLookupFunction;
382388
};
383389

0 commit comments

Comments
 (0)