Merge branch 'master' of CorentinB/uGFX into master

ugfx_release_2.7
Joel Bodenmann 2016-12-11 17:40:38 +01:00 committed by Gogs
commit 81fc34801d
2 changed files with 144 additions and 0 deletions

View File

@ -1911,6 +1911,125 @@ void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
}
#endif
#if GDISP_NEED_ARC
#if (!GMISC_NEED_FIXEDTRIG && !GMISC_NEED_FASTTRIG) || !GFX_USE_GMISC
#include <math.h>
#endif
void gdispGDrawThickArc(GDisplay *g, coord_t xc, coord_t yc, coord_t radiusStart, coord_t radiusEnd, coord_t start, coord_t end, color_t color) {
coord_t x, y, d, r;
coord_t startTan, endTan, curangle;
coord_t precision = 512;
// Normalize the angles
if (start < 0)
start -= (start/360-1)*360;
else if (start >= 360)
start %= 360;
if (end < 0)
end -= (end/360-1)*360;
else if (end >= 360)
end %= 360;
#if GFX_USE_GMISC && GMISC_NEED_FIXEDTRIG
if((start / 45) % 2 == 0){
startTan = ffsin(start % 45) * precision / ffcos(start % 45) + start / 45 * precision;}
else{
startTan = ffsin(start % 45 - 45) * precision / ffcos(start % 45 - 45) + start / 45 * precision + precision;}
if((end / 45) % 2 == 0){
endTan = ffsin(end % 45) * precision / ffcos(end % 45) + end / 45 * precision;}
else{
endTan = ffsin(end % 45 - 45) * precision / ffcos(end % 45 - 45) + end / 45 * precision + precision;}
#elif GFX_USE_GMISC && GMISC_NEED_FASTTRIG
if((start / 45) % 2 == 0){
startTan = fsin(start % 45) * precision / fcos(start % 45) + start / 45 * precision;}
else{
startTan = fsin(start % 45 - 45) * precision / fcos(start % 45 - 45) + start / 45 * precision + precision;}
if((end / 45) % 2 == 0){
endTan = fsin(end % 45) * precision / fcos(end % 45) + end / 45 * precision;}
else{
endTan = fsin(end % 45 - 45) * precision / fcos(end % 45 - 45) + end / 45 * precision + precision;}
#else
if((start / 45) % 2 == 0){
startTan = (tan((start % 45)*GFX_PI/180) + start / 45)* precision;}
else{
startTan = (1+tan((start % 45 - 45)*GFX_PI/180) + start / 45)* precision;}
if((end / 45) % 2 == 0){
endTan = (tan((end % 45) *GFX_PI/180) + end / 45) * precision;}
else{
endTan = (1+tan((end % 45 - 45) *GFX_PI/180) + end / 45) * precision;}
#endif
MUTEX_ENTER(g);
g->p.color = color;
//Draw concentric circles using Andres algorithm
for(r = radiusStart; r <= radiusEnd; r++)
{
x = 0;
y = r;
d = r - 1;
while (y >= x){
//approximate tan
curangle = x*precision/y;
if(end > start){
g->p.color = color;
//Draw points by symmetry
if(curangle > startTan && curangle < endTan){g->p.y = yc - x; g->p.x = xc + y; drawpixel_clip(g);}
if(curangle + 2*precision > startTan && curangle + 2*precision < endTan){g->p.y = yc - y; g->p.x = xc - x; drawpixel_clip(g);}
if(curangle + 4*precision > startTan && curangle + 4*precision < endTan){g->p.y = yc + x; g->p.x = xc - y; drawpixel_clip(g);}
if(curangle + 6*precision > startTan && curangle + 6*precision < endTan){g->p.y = yc + y; g->p.x = xc + x; drawpixel_clip(g);}
curangle = precision - curangle;
if(curangle + precision > startTan && curangle + precision < endTan){g->p.y = yc - y; g->p.x = xc + x; drawpixel_clip(g);}
if(curangle + 3*precision > startTan && curangle + 3*precision < endTan){g->p.y = yc - x; g->p.x = xc - y; drawpixel_clip(g);}
if(curangle + 5*precision > startTan && curangle + 5*precision < endTan){g->p.y = yc + y; g->p.x = xc - x; drawpixel_clip(g);}
if(curangle + 7*precision > startTan && curangle + 7*precision < endTan){g->p.y = yc + x; g->p.x = xc + y; drawpixel_clip(g);}
}
else{
//Draw points by symmetry
if(curangle > startTan || curangle < endTan){g->p.y = yc - x; g->p.x = xc + y; drawpixel_clip(g);}
if(curangle + 2*precision > startTan || curangle + 2*precision < endTan){g->p.y = yc - y; g->p.x = xc - x; drawpixel_clip(g);}
if(curangle + 4*precision > startTan || curangle + 4*precision < endTan){g->p.y = yc + x; g->p.x = xc - y; drawpixel_clip(g);}
if(curangle + 6*precision > startTan || curangle + 6*precision < endTan){g->p.y = yc + y; g->p.x = xc + x; drawpixel_clip(g);}
curangle = precision - curangle;
if(curangle + precision > startTan || curangle + precision < endTan){g->p.y = yc - y; g->p.x = xc + x; drawpixel_clip(g);}
if(curangle + 3*precision > startTan || curangle + 3*precision < endTan){g->p.y = yc - x; g->p.x = xc - y; drawpixel_clip(g);}
if(curangle + 5*precision > startTan || curangle + 5*precision < endTan){g->p.y = yc + y; g->p.x = xc - x; drawpixel_clip(g);}
if(curangle + 7*precision > startTan || curangle + 7*precision < endTan){g->p.y = yc + x; g->p.x = xc + y; drawpixel_clip(g);}
}
//Compute next point
if (d >= 2 * x){
d -= 2 * x + 1;
x++;
}
else if (d < 2 * (r - y)){
d += 2 * y - 1;
y--;
}
else{
d += 2 * (y - x - 1);
y--;
x++;
}
}
}
autoflush(g);
MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ARC
void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
coord_t a, b, P;

View File

@ -711,6 +711,31 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
#define gdispDrawArc(x,y,r,s,e,c) gdispGDrawArc(GDISP,x,y,r,s,e,c)
/*
* @brief Draw a thick arc.
* @pre GDISP_NEED_ARC must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] xc,yc The center point
* @param[in] startradius The inner radius of the thick arc
* @param[in] endradius The outer radius of the thick arc
* @param[in] startangle The start angle (0 to 360)
* @param[in] endangle The end angle (0 to 360)
* @param[in] color The color of the arc
*
* @note This routine requires trig support. It can either come from your C runtime library
* cos() and sin() which requires floating point support (and is slow), or you can define GFX_USE_GMISC
* and either GMISC_NEED_FIXEDTRIG or GMISC_NEED_FASTTRIG.
* GMISC_NEED_FASTTRIG uses table based floating point trig operations.
* GMISC_NEED_FIXEDTRIG uses fixed point integer trig operations.
* Note accuracy on both the table based options are more than adequate for the one degree
* resolution provided by these arc routines. Both are much faster than your C runtime library.
*
* @api
*/
void gdispGDrawThickArc(GDisplay *g, coord_t xc, coord_t yc, coord_t startradius, coord_t endradius, coord_t startangle, coord_t endangle, color_t color);
#define gdispDrawThickArc(x,y,rs,re,s,e,c) gdispGDrawThickArc(GDISP,x,y,rs,re,s,e,c)
/*
* @brief Draw a filled arc.
* @pre GDISP_NEED_ARC must be TRUE in your gfxconf.h