Skip to content

Commit

Permalink
add drawBezier function
Browse files Browse the repository at this point in the history
  • Loading branch information
lovyan03 committed May 26, 2020
1 parent f407343 commit 143d3ae
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 12 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ void setup(void)
drawLine ( x0, y0, x1, y1 , color); // 2点間の直線
drawTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の外周
fillTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の塗り
drawArc ( x, y, r1, r2, angle1, angle2, color); // 円弧の外周
fillArc ( x, y, r1, r2, angle1, angle2, color); // 円弧の塗り
drawBezier ( x0, y0, x1, y1, x2, y2, color); // 3点間のベジエ曲線
drawArc ( x, y, r0, r1, angle0, angle1, color); // 円弧の外周
fillArc ( x, y, r0, r1, angle0, angle1, color); // 円弧の塗り
*/


Expand Down
5 changes: 3 additions & 2 deletions examples/HowToUse/1_simple_use/1_simple_use.ino
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ void setup(void)
drawLine ( x0, y0, x1, y1 , color); // 2点間の直線
drawTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の外周
fillTriangle ( x0, y0, x1, y1, x2, y2, color); // 3点間の三角形の塗り
drawArc ( x, y, r1, r2, angle1, angle2, color); // 円弧の外周
fillArc ( x, y, r1, r2, angle1, angle2, color); // 円弧の塗り
drawBezier ( x0, y0, x1, y1, x2, y2, color); // 3点間のベジエ曲線
drawArc ( x, y, r0, r1, angle0, angle1, color); // 円弧の外周
fillArc ( x, y, r0, r1, angle0, angle1, color); // 円弧の塗り
*/


Expand Down
91 changes: 87 additions & 4 deletions src/lgfx/lgfx_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,89 @@ namespace lgfx
endWrite();
}

void LGFXBase::drawBezier( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2)
{
std::int32_t x = x0 - x1, y = y0 - y1;
double t = x0 - 2 * x1 + x2, r;

startWrite();

if (x * (x2 - x1) > 0) {
if (y * (y2 - y1) > 0)
if (fabs((y0 - 2 * y1 + y2) / t * x) > abs(y)) {
x0 = x2; x2 = x + x1; y0 = y2; y2 = y + y1;
}
t = (x0 - x1) / t;
r = (1 - t) * ((1 - t) * y0 + 2.0 * t * y1) + t * t * y2;
t = (x0 * x2 - x1 * x1) * t / (x0 - x1);
x = floor(t + 0.5); y = floor(r + 0.5);
r = (y1 - y0) * (t - x0) / (x1 - x0) + y0;
drawBezierHelper(x0, y0, x, floor(r + 0.5), x, y);
r = (y1 - y2) * (t - x2) / (x1 - x2) + y2;
x0 = x1 = x; y0 = y; y1 = floor(r + 0.5);
}
if ((y0 - y1) * (y2 - y1) > 0) {
t = y0 - 2 * y1 + y2; t = (y0 - y1) / t;
r = (1 - t) * ((1 - t) * x0 + 2.0 * t * x1) + t * t * x2;
t = (y0 * y2 - y1 * y1) * t / (y0 - y1);
x = floor(r + 0.5); y = floor(t + 0.5);
r = (x1 - x0) * (t - y0) / (y1 - y0) + x0;
drawBezierHelper(x0, y0, floor(r + 0.5), y, x, y);
r = (x1 - x2) * (t - y2) / (y1 - y2) + x2;
x0 = x; x1 = floor(r + 0.5); y0 = y1 = y;
}
drawBezierHelper(x0, y0, x1, y1, x2, y2);

endWrite();
}

void LGFXBase::drawBezierHelper( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2)
{
// Check if coordinates are sequential (replaces assert)
if (((x2 >= x1 && x1 >= x0) || (x2 <= x1 && x1 <= x0))
&& ((y2 >= y1 && y1 >= y0) || (y2 <= y1 && y1 <= y0)))
{
// Coordinates are sequential
std::int32_t sx = x2 - x1, sy = y2 - y1;
std::int32_t xx = x0 - x1, yy = y0 - y1, xy;
float dx, dy, err, cur = xx * sy - yy * sx;

if (sx * (std::int32_t)sx + sy * (std::int32_t)sy > xx * xx + yy * yy) {
x2 = x0; x0 = sx + x1; y2 = y0; y0 = sy + y1; cur = -cur;
}
if (cur != 0) {
xx += sx; xx *= sx = x0 < x2 ? 1 : -1;
yy += sy; yy *= sy = y0 < y2 ? 1 : -1;
xy = 2 * xx * yy; xx *= xx; yy *= yy;
if (cur * sx * sy < 0) {
xx = -xx; yy = -yy; xy = -xy; cur = -cur;
}
dx = 4.0 * sy * cur * (x1 - x0) + xx - xy;
dy = 4.0 * sx * cur * (y0 - y1) + yy - xy;
xx += xx; yy += yy; err = dx + dy + xy;
do {
drawPixel(x0, y0);
if (x0 == x2 && y0 == y2)
{
return;
}
y1 = 2 * err < dx;
if (2 * err > dy) {
x0 += sx;
dx -= xy;
err += dy += yy;
}
if ( y1 ) {
y0 += sy;
dy -= xy;
err += dx += xx;
}
} while (dy < dx );
}
drawLine(x0, y0, x2, y2);
}
}

void LGFXBase::drawGradientLine( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, bgr888_t colorstart, bgr888_t colorend )
{
if ( colorstart == colorend || (x0 == x1 && y0 == y1)) {
Expand Down Expand Up @@ -828,8 +911,8 @@ namespace lgfx
// std::uint32_t x_mask = (1 << (4 - __builtin_ffs(param->src_bits))) - 1;
// std::uint32_t x_mask = (1 << ((~(param->src_bits>>1)) & 3)) - 1;
std::uint32_t x_mask = (param->src_bits == 1) ? 7
: (param->src_bits == 2) ? 3
: 1;
: (param->src_bits == 2) ? 3
: 1;
param->src_width = (w + x_mask) & (~x_mask);
}

Expand Down Expand Up @@ -896,8 +979,8 @@ namespace lgfx
// std::uint32_t x_mask = (1 << (4 - __builtin_ffs(param->src_bits))) - 1;
// std::uint32_t x_mask = (1 << ((~(param->src_bits>>1)) & 3)) - 1;
std::uint32_t x_mask = (param->src_bits == 1) ? 7
: (param->src_bits == 2) ? 3
: 1;
: (param->src_bits == 2) ? 3
: 1;
param->src_width = (w + x_mask) & (~x_mask);
} else {
param->src_width = w;
Expand Down
12 changes: 8 additions & 4 deletions src/lgfx/lgfx_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,14 @@ namespace lgfx
void drawTriangle ( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2);
template<typename T> inline void fillTriangle ( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2, const T& color) { setColor(color); fillTriangle(x0, y0, x1, y1, x2, y2); }
void fillTriangle ( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2);
template<typename T> inline void drawArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float start, float end, const T& color) { setColor(color); drawArc( x, y, r0, r1, start, end); }
void drawArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float start, float end);
template<typename T> inline void fillArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float start, float end, const T& color) { setColor(color); fillArc( x, y, r0, r1, start, end); }
void fillArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float start, float end);
template<typename T> inline void drawBezier ( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2, const T& color) { setColor(color); drawBezier(x0, y0, x1, y1, x2, y2); }
void drawBezier ( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2);
template<typename T> inline void drawBezierHelper(std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2, const T& color) { setColor(color); drawBezierHelper(x0, y0, x1, y1, x2, y2); }
void drawBezierHelper(std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, std::int32_t x2, std::int32_t y2);
template<typename T> inline void drawArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float angle0, float angle1, const T& color) { setColor(color); drawArc( x, y, r0, r1, angle0, angle1); }
void drawArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float angle0, float angle1);
template<typename T> inline void fillArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float angle0, float angle1, const T& color) { setColor(color); fillArc( x, y, r0, r1, angle0, angle1); }
void fillArc ( std::int32_t x, std::int32_t y, std::int32_t r0, std::int32_t r1, float angle0, float angle1);
template<typename T> inline void drawCircleHelper(std::int32_t x, std::int32_t y, std::int32_t r, std::uint_fast8_t cornername , const T& color) { setColor(color); drawCircleHelper(x, y, r, cornername ); }
void drawCircleHelper(std::int32_t x, std::int32_t y, std::int32_t r, std::uint_fast8_t cornername);
template<typename T> inline void fillCircleHelper(std::int32_t x, std::int32_t y, std::int32_t r, std::uint_fast8_t corners, std::int32_t delta, const T& color) { setColor(color); fillCircleHelper(x, y, r, corners, delta); }
Expand Down

0 comments on commit 143d3ae

Please sign in to comment.