Aktualizace o kresleni trojuhelniku

This commit is contained in:
Pavel Brychta 2021-08-14 12:18:15 +02:00
parent eded1d270a
commit 2f040fc77f
2 changed files with 141 additions and 25 deletions

View File

@ -65,7 +65,7 @@ bool OLEDDisplay::allocateBuffer() {
logBufferMaxLines = 0;
logBuffer = NULL;
if (!this->connect()) {
if (!connect()) {
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Can't establish connection to display\n");
return false;
}
@ -302,6 +302,90 @@ void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) {
}
void OLEDDisplay::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
int16_t x2, int16_t y2) {
drawLine(x0, y0, x1, y1);
drawLine(x1, y1, x2, y2);
drawLine(x2, y2, x0, y0);
}
void OLEDDisplay::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1,
int16_t x2, int16_t y2) {
int16_t a, b, y, last;
if (y0 > y1) {
_swap_int16_t(y0, y1);
_swap_int16_t(x0, x1);
}
if (y1 > y2) {
_swap_int16_t(y2, y1);
_swap_int16_t(x2, x1);
}
if (y0 > y1) {
_swap_int16_t(y0, y1);
_swap_int16_t(x0, x1);
}
if (y0 == y2) {
a = b = x0;
if (x1 < a) {
a = x1;
} else if (x1 > b) {
b = x1;
}
if (x2 < a) {
a = x2;
} else if (x2 > b) {
b = x2;
}
drawHorizontalLine(a, y0, b - a + 1);
return;
}
int16_t
dx01 = x1 - x0,
dy01 = y1 - y0,
dx02 = x2 - x0,
dy02 = y2 - y0,
dx12 = x2 - x1,
dy12 = y2 - y1;
int32_t
sa = 0,
sb = 0;
if (y1 == y2) {
last = y1; // Include y1 scanline
} else {
last = y1 - 1; // Skip it
}
for (y = y0; y <= last; y++) {
a = x0 + sa / dy01;
b = x0 + sb / dy02;
sa += dx01;
sb += dx02;
if (a > b) {
_swap_int16_t(a, b);
}
drawHorizontalLine(a, y, b - a + 1);
}
sa = dx12 * (y - y1);
sb = dx02 * (y - y0);
for (; y <= y2; y++) {
a = x1 + sa / dy12;
b = x0 + sb / dy02;
sa += dx12;
sb += dx02;
if (a > b) {
_swap_int16_t(a, b);
}
drawHorizontalLine(a, y, b - a + 1);
}
}
void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) {
if (y < 0 || y >= this->height()) { return; }
@ -451,7 +535,7 @@ void OLEDDisplay::drawXbm(int16_t xMove, int16_t yMove, int16_t width, int16_t h
}
}
void OLEDDisplay::drawIco16x16(int16_t xMove, int16_t yMove, const char *ico, bool inverse) {
void OLEDDisplay::drawIco16x16(int16_t xMove, int16_t yMove, const uint8_t *ico, bool inverse) {
uint16_t data;
for(int16_t y = 0; y < 16; y++) {
@ -549,6 +633,15 @@ void OLEDDisplay::drawString(int16_t xMove, int16_t yMove, const String &strUser
free(text);
}
void OLEDDisplay::drawStringf( int16_t x, int16_t y, char* buffer, String format, ... )
{
va_list myargs;
va_start(myargs, format);
vsprintf(buffer, format.c_str(), myargs);
va_end(myargs);
drawString( x, y, buffer );
}
void OLEDDisplay::drawStringMaxWidth(int16_t xMove, int16_t yMove, uint16_t maxLineWidth, const String &strUser) {
uint16_t firstChar = pgm_read_byte(fontData + FIRST_CHAR_POS);
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
@ -836,21 +929,30 @@ int OLEDDisplay::_putc(int c) {
// Private functions
void OLEDDisplay::setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width, uint16_t height) {
this->geometry = g;
switch (g) {
case GEOMETRY_128_64:
this->displayWidth = 128;
this->displayHeight = 64;
break;
case GEOMETRY_128_32:
this->displayWidth = 128;
this->displayHeight = 32;
break;
case GEOMETRY_RAWMODE:
this->displayWidth = width > 0 ? width : 128;
this->displayHeight = height > 0 ? height : 64;
break;
case GEOMETRY_128_64:
this->displayWidth = 128;
this->displayHeight = 64;
break;
case GEOMETRY_128_32:
this->displayWidth = 128;
this->displayHeight = 32;
break;
case GEOMETRY_64_48:
this->displayWidth = 64;
this->displayHeight = 48;
break;
case GEOMETRY_64_32:
this->displayWidth = 64;
this->displayHeight = 32;
break;
case GEOMETRY_RAWMODE:
this->displayWidth = width > 0 ? width : 128;
this->displayHeight = height > 0 ? height : 64;
break;
}
this->displayBufferSize = displayWidth * displayHeight /8;
this->displayBufferSize = displayWidth * displayHeight / 8;
}
void OLEDDisplay::sendInitCommands(void) {
@ -863,7 +965,10 @@ void OLEDDisplay::sendInitCommands(void) {
sendCommand(this->height() - 1);
sendCommand(SETDISPLAYOFFSET);
sendCommand(0x00);
sendCommand(SETSTARTLINE);
if(geometry == GEOMETRY_64_32)
sendCommand(0x00);
else
sendCommand(SETSTARTLINE);
sendCommand(CHARGEPUMP);
sendCommand(0x14);
sendCommand(MEMORYMODE);
@ -872,7 +977,7 @@ void OLEDDisplay::sendInitCommands(void) {
sendCommand(COMSCANINC);
sendCommand(SETCOMPINS);
if (geometry == GEOMETRY_128_64) {
if (geometry == GEOMETRY_128_64 || geometry == GEOMETRY_64_48 || geometry == GEOMETRY_64_32) {
sendCommand(0x12);
} else if (geometry == GEOMETRY_128_32) {
sendCommand(0x02);
@ -880,7 +985,7 @@ void OLEDDisplay::sendInitCommands(void) {
sendCommand(SETCONTRAST);
if (geometry == GEOMETRY_128_64) {
if (geometry == GEOMETRY_128_64 || geometry == GEOMETRY_64_48 || geometry == GEOMETRY_64_32) {
sendCommand(0xCF);
} else if (geometry == GEOMETRY_128_32) {
sendCommand(0x8F);

View File

@ -137,8 +137,10 @@ enum OLEDDISPLAY_TEXT_ALIGNMENT {
enum OLEDDISPLAY_GEOMETRY {
GEOMETRY_128_64 = 0,
GEOMETRY_128_32,
GEOMETRY_RAWMODE,
GEOMETRY_128_32 = 1,
GEOMETRY_64_48 = 2,
GEOMETRY_64_32 = 3,
GEOMETRY_RAWMODE = 4
};
enum HW_I2C {
@ -220,6 +222,12 @@ class OLEDDisplay : public Stream {
// Fill circle
void fillCircle(int16_t x, int16_t y, int16_t radius);
// Draw an empty triangle i.e. only the outline
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
// Draw a solid triangle i.e. filled
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
// Draw a line horizontally
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
@ -237,24 +245,27 @@ class OLEDDisplay : public Stream {
void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm);
// Draw icon 16x16 xbm format
void drawIco16x16(int16_t x, int16_t y, const char *ico, bool inverse = false);
void drawIco16x16(int16_t x, int16_t y, const uint8_t *ico, bool inverse = false);
/* Text functions */
// Draws a string at the given location
void drawString(int16_t x, int16_t y, const String& text);
void drawString(int16_t x, int16_t y, const String &text);
// Draws a formatted string (like printf) at the given location
void drawStringf(int16_t x, int16_t y, char* buffer, String format, ... );
// Draws a String with a maximum width at the given location.
// If the given String is wider than the specified width
// The text will be wrapped to the next line at a space or dash
void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String& text);
void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text);
// Returns the width of the const char* with the current
// font settings
uint16_t getStringWidth(const char* text, uint16_t length);
// Convencience method for the const char version
uint16_t getStringWidth(const String& text);
uint16_t getStringWidth(const String &text);
uint16_t getTextHeight(void);
@ -378,7 +389,7 @@ class OLEDDisplay : public Stream {
void sendInitCommands();
// converts utf8 characters to extended ascii
char* utf8ascii(const String& s);
char* utf8ascii(const String &s);
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));