mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2025-08-03 12:44:46 +02:00
Update drawArc, add new example
This commit is contained in:
33
TFT_eSPI.cpp
33
TFT_eSPI.cpp
@@ -3895,7 +3895,7 @@ void TFT_eSPI::drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_
|
||||
{
|
||||
inTransaction = true;
|
||||
|
||||
if (endAngle != startAngle)
|
||||
if (endAngle != startAngle && (startAngle != 0 || endAngle != 360))
|
||||
{
|
||||
float sx = -sinf(startAngle * deg2rad);
|
||||
float sy = +cosf(startAngle * deg2rad);
|
||||
@@ -3927,17 +3927,9 @@ void TFT_eSPI::drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_
|
||||
drawWedgeLine(asx, asy, aex, aey, 0.3, 0.3, fg_color, bg_color);
|
||||
}
|
||||
|
||||
if (endAngle > startAngle)
|
||||
{
|
||||
// Draw arc in single sweep
|
||||
drawArc(x, y, r, ir, startAngle, endAngle, fg_color, bg_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arc sweeps through 6 o'clock so draw in two parts
|
||||
drawArc(x, y, r, ir, startAngle, 360, fg_color, bg_color);
|
||||
drawArc(x, y, r, ir, 0, endAngle, fg_color, bg_color);
|
||||
}
|
||||
// Draw arc
|
||||
drawArc(x, y, r, ir, startAngle, endAngle, fg_color, bg_color);
|
||||
|
||||
}
|
||||
else // Draw full 360
|
||||
{
|
||||
@@ -3949,7 +3941,7 @@ void TFT_eSPI::drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: sqrt_fraction
|
||||
** Function name: sqrt_fraction (private function)
|
||||
** Description: Smooth graphics support function for alpha derivation
|
||||
***************************************************************************************/
|
||||
// Compute the fixed point square root of an integer and
|
||||
@@ -3983,7 +3975,7 @@ inline uint8_t TFT_eSPI::sqrt_fraction(uint32_t num) {
|
||||
***************************************************************************************/
|
||||
// Centre at x,y
|
||||
// r = arc outer radius, ir = arc inner radius. Inclusive, so arc thickness = r-ir+1
|
||||
// Angles MUST be in range 0-360, end angle MUST be greater than start angle
|
||||
// Angles MUST be in range 0-360
|
||||
// Arc foreground fg_color anti-aliased with background colour along sides
|
||||
// smooth is optional, default is true, smooth=false means no antialiasing
|
||||
// Note: Arc ends are not anti-aliased (use drawSmoothArc instead for that)
|
||||
@@ -3992,10 +3984,15 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
||||
uint32_t fg_color, uint32_t bg_color,
|
||||
bool smooth)
|
||||
{
|
||||
if (_vpOoB) return;
|
||||
if (endAngle < startAngle) {
|
||||
// Arc sweeps through 6 o'clock so draw in two parts
|
||||
drawArc(x, y, r, ir, startAngle, 360, fg_color, bg_color, smooth);
|
||||
startAngle = 0;
|
||||
}
|
||||
|
||||
if (_vpOoB || startAngle == endAngle) return;
|
||||
if (r < ir) transpose(r, ir); // Required that r > ir
|
||||
if (r <= 0 || ir < 0) return; // Invalid r, ir can be zero (circle sector)
|
||||
if (endAngle < startAngle) transpose(startAngle, endAngle);
|
||||
if (startAngle < 0) startAngle = 0;
|
||||
if (endAngle > 360) endAngle = 360;
|
||||
|
||||
@@ -4020,8 +4017,8 @@ void TFT_eSPI::drawArc(int32_t x, int32_t y, int32_t r, int32_t ir,
|
||||
// ---¦--- Arc quadrant index
|
||||
// 0 | 3
|
||||
// Fixed point U16.16 slope table for arc start/end in each quadrant
|
||||
uint32_t startSlope[4] = {0, 0, 0xFFFFFFFF, 0};
|
||||
uint32_t endSlope[4] = {0, 0xFFFFFFFF, 0, 0};
|
||||
uint32_t startSlope[4] = {0, 0, 0xFFFFFFFF, 0};
|
||||
uint32_t endSlope[4] = {0, 0xFFFFFFFF, 0, 0};
|
||||
|
||||
// Ensure maximum U16.16 slope of arc ends is ~ 0x8000 0000
|
||||
constexpr float minDivisor = 1.0f/0x8000;
|
||||
|
@@ -530,9 +530,9 @@ class TFT_eSPI : public Print { friend class TFT_eSprite; // Sprite class has ac
|
||||
// The start angle may be larger than the end angle. Arcs are always drawn clockwise from the start angle.
|
||||
void drawSmoothArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool roundEnds = false);
|
||||
|
||||
// As per "drawSmoothArc" except endAngle should be greater than startAngle (angles will be swapped otherwise)
|
||||
// As per "drawSmoothArc" except the ends of the arc are NOT anti-aliased, this facilitates dynamic arc length changes with
|
||||
// arc segments and ensures clean segment joints.
|
||||
// The sides of the arc are anti-aliased by default. If smoothArc is false sides will NOT be anti-aliased
|
||||
// The ends of the arc are NOT anti-aliased, this facilitates dynamic arc length changes with arc segments and ensures clean segment joints
|
||||
void drawArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle, uint32_t fg_color, uint32_t bg_color, bool smoothArc = true);
|
||||
|
||||
// Draw an anti-aliased filled circle at x, y with radius r
|
||||
|
47
examples/Smooth Graphics/Colour_Wheel/Colour_Wheel.ino
Normal file
47
examples/Smooth Graphics/Colour_Wheel/Colour_Wheel.ino
Normal file
@@ -0,0 +1,47 @@
|
||||
// Arc drawing example - draw a colour wheel
|
||||
|
||||
#include <TFT_eSPI.h> // Include the graphics library
|
||||
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
|
||||
|
||||
uint16_t colors[12];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Setup
|
||||
// -------------------------------------------------------------------------
|
||||
void setup(void) {
|
||||
Serial.begin(115200);
|
||||
tft.init();
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
|
||||
// Create the outer ring colours
|
||||
for (uint8_t c = 0; c < 2; c++) {
|
||||
colors[c + 10] = tft.alphaBlend(128 + c * 127, TFT_RED, TFT_MAGENTA);
|
||||
colors[c + 8] = tft.alphaBlend(128 + c * 127, TFT_MAGENTA, TFT_BLUE);
|
||||
colors[c + 6] = tft.alphaBlend(128 + c * 127, TFT_BLUE, TFT_GREEN);
|
||||
colors[c + 4] = tft.alphaBlend(128 + c * 127, TFT_GREEN, TFT_YELLOW);
|
||||
colors[c + 2] = tft.alphaBlend(128 + c * 127, TFT_YELLOW, TFT_ORANGE);
|
||||
colors[c + 0] = tft.alphaBlend(128 + c * 127, TFT_ORANGE, TFT_RED);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Main loop
|
||||
// -------------------------------------------------------------------------
|
||||
void loop() {
|
||||
uint16_t rDelta = (tft.width() - 1) / 10;
|
||||
uint16_t x = tft.width() / 2;
|
||||
uint16_t y = tft.height() / 2;
|
||||
bool smooth = true;
|
||||
|
||||
// Draw rings as a series of arcs, increasingly blend colour with white towards middle
|
||||
for (uint16_t i = 5; i > 0; i--) {
|
||||
for (uint16_t angle = 0; angle <= 330; angle += 30) {
|
||||
uint16_t radius = i * rDelta;
|
||||
uint16_t wheelColor = tft.alphaBlend((i * 255.0)/5.0, colors[angle / 30], TFT_WHITE);
|
||||
tft.drawArc(x, y, radius, radius - rDelta, angle, angle + 30, wheelColor, TFT_BLACK, smooth);
|
||||
}
|
||||
smooth = false; // Only outer ring is smooth
|
||||
}
|
||||
|
||||
while (1) delay(100);
|
||||
}
|
@@ -7,8 +7,6 @@
|
||||
// The sides of the arc can optionally be smooth or not. Smooth arcs have
|
||||
// a much better appearance, especially at small sizes.
|
||||
|
||||
// Start angle for drawArc must be smaller than end angle
|
||||
|
||||
#include <TFT_eSPI.h> // Include the graphics library
|
||||
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
|
||||
|
||||
@@ -42,7 +40,7 @@ void loop()
|
||||
|
||||
// 0 degrees is at 6 o'clock position
|
||||
// Arcs are drawn clockwise from start_angle to end_angle
|
||||
// Start angle for drawArc must be smaller than end angle (function will swap them otherwise)
|
||||
// Start angle can be greater than end angle, the arc will then be drawn through 0 degrees
|
||||
uint16_t start_angle = random(361); // Start angle must be in range 0 to 360
|
||||
uint16_t end_angle = random(361); // End angle must be in range 0 to 360
|
||||
|
||||
@@ -50,35 +48,6 @@ void loop()
|
||||
|
||||
tft.drawArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color, smooth);
|
||||
|
||||
//tft.drawArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color); // always smooth sides if parameter is missing
|
||||
|
||||
// The following function allows arcs to be drawn through the 6 o'clock position by drawing in 2 segments if
|
||||
// the start angle is greater than the end angle
|
||||
//drawAnyArc(x, y, radius, inner_radius, start_angle, end_angle, fg_color, bg_color, smooth); // smooth sides if parameter is missing
|
||||
|
||||
count++;
|
||||
if (count < 30) delay(500); // After 15s draw as fast as possible!
|
||||
}
|
||||
|
||||
|
||||
// The following function allows arcs to be drawn through the 0 degree position by drawing in 2 segments
|
||||
|
||||
// Function prototype with default smooth setting
|
||||
void drawAnyArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle,
|
||||
uint32_t fg_color, uint32_t bg_color, bool smooth = true);
|
||||
|
||||
void drawAnyArc(int32_t x, int32_t y, int32_t r, int32_t ir, int32_t startAngle, int32_t endAngle,
|
||||
uint32_t fg_color, uint32_t bg_color, bool smooth)
|
||||
{
|
||||
if (endAngle > startAngle)
|
||||
{
|
||||
// Draw arc in single sweep
|
||||
tft.drawArc(x, y, r, ir, startAngle, endAngle, fg_color, bg_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Arc sweeps through 6 o'clock so draw in two parts
|
||||
tft.drawArc(x, y, r, ir, startAngle, 360, fg_color, bg_color);
|
||||
tft.drawArc(x, y, r, ir, 0, endAngle, fg_color, bg_color);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user