大家有没有画实心圆的算法?

2019-12-28 17:50发布

就是用LCD画一个实心圆~~不是空心的哦~~是实心,可以填充任意颜 {MOD}的~~~
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
55条回答
tyoo
1楼-- · 2019-12-28 22:27
当然有,计算机图形学 这本书讲得很详细,从点到线,再到各种几何图形
channe
2楼-- · 2019-12-29 02:21
 精彩回答 2  元偷偷看……
senjet
3楼-- · 2019-12-29 06:56
void FillCircle(int x0,int y0,int r,int mode)
{
int x,y;
int deltax,deltay;
int d;
int xi;
x=0;
y=r;
deltax=3;
deltay=2-r-r;
d=1-r;

draw(x+x0,y+y0,mode);
draw(x+x0,-y+y0,mode);
for(xi=-r+x0;xi<=r+x0;xi++)
        draw(xi,y0,mode);//水平线填充
while(x<y)
{
   if(d<0)
   {
     d+=deltax;
     deltax+=2;
     x++;
   }
   else
   {
     d+=(deltax+deltay);
     deltax+=2;
     deltay+=2;
     x++;
     y--;
   }
   for(xi=-x+x0;xi<=x+x0;xi++)
   {
     draw(xi,-y+y0,mode);
     draw(xi,y+y0,mode);//扫描线填充
   }
   for(xi=-y+x0;xi<=y+x0;xi++)
   {
     draw(xi,-x+y0,mode);
     draw(xi,x+y0,mode);//扫描线填充其量
   }
  }
}
myqiang1990
4楼-- · 2019-12-29 09:50
senjet 发表于 2013-8-24 15:27
void FillCircle(int x0,int y0,int r,int mode)
{
int x,y;

你这个draw函数的底层是干什么的?还有mode?
STM32_Study
5楼-- · 2019-12-29 11:39
直接用勾股定理就可以了。

知道半径R,知道圆心坐标,那就可以算出四分之一圆的坐标,通过跟圆心坐标的加减换算,可以得出上半圆的坐标,然后分别与圆心换算,得出下半圆的坐标,并每个上下坐标画垂直线。

也可以左右画线,看LCD驱动哪个实现起来更高速

senjet
6楼-- · 2019-12-29 16:17
本帖最后由 senjet 于 2013-8-24 15:50 编辑
myqiang1990 发表于 2013-8-24 15:35
你这个draw函数的底层是干什么的?还有mode?


就是在x,y处画点啊,mode是颜 {MOD}。这是快速画填充圆算法。相应的还有画线、画非填充圆、画椭圆,全部以画点为基础。
void line(uchar x0,uchar y0,uchar x1, uchar y1,uchar mode)
{         int e; //e 表示实际直线中的某一点与像素中点之间的距离  
           uchar i,x,y,dx,dy,tmp;
        signed char sx,sy;
        char exchange=0;

    x = x0;
    y = y0;
        if(x1>=x0)
                dx=x1-x0;
        else
                dx=x0-x1;
        if(y1>=y0)
                dy=y1-y0;
        else
                dy=y0-y1;

    //计算坐标的增量:1,0 or -1  
    sx = (x1 - x0) == 0  ? 0 : ( (x1 - x0) < 0  ? -1 : 1);
    sy = (y1 - y0) == 0  ? 0 : ( (y1 - y0) < 0  ? -1 : 1);
    //斜率的绝对值 >1 or <1
    if (dy > dx)
    {   tmp = dx;
        dx  = dy;
        dy  = tmp;
        exchange = 1;
    }

    //非整数算法中 e = dy / dx - 1/2  
    //现在扩大了(2 * dx)倍  
    e = 2 * dy - dx;  

    for (i=1;i<=dx+1;i++)
    {
        //自定义的绘制像素的函数
        draw(x,y,mode);

        while (e > 0)
        {
            if (exchange)
                x += sx;
            else
                y += sy;
         
            //非整数算法中 e -= 1  
            //现在扩大了(2 * dx)倍  
            e -= 2 * dx;
        }

        //当斜率绝对值大于1时,y坐标总是增加一个单位  
        if (exchange)
            y += sy;
        else
            x += sx;

        e += 2 * dy;
        }

}

void circle(uchar x,uchar y,uchar R,uchar mode)
{
//圆心(x1,y1),当前像素I(xi,yi),右像素H(xi+1,y),右下像素D(xi+1,yi-1),下像素V(xi,yi-1)
int xi,yi,dd,m,n;
//圆心距差值平方dh=(xi+1)*(xi+1)+yi*yi-R*R; dd=(xi+1)*(xi+1)+(yi-1)*(yi-1)-R*R; dv=xi*xi+(yi-1)*(yi-1)-R*R;
xi=0; //起点(0,R)
yi=R;
dd=2-2*R; //起点的右下像素(1,R-1)的圆心距差值dd=1+(R-1)*(R-1)-R*R
while(yi>=xi) //循环到八分之一圆;yi>=0即可以画出四分圆
{
   draw(xi+x,yi+y,mode);   //2区,坐标平移(x,y)画圆
   draw(yi+x,xi+y,mode);   //1区
   draw(-xi+x,yi+y,mode); //3区
   draw(-yi+x,xi+y,mode); //4区
   draw(-yi+x,-xi+y,mode); //5区
   draw(-xi+x,-yi+y,mode); //6区
   draw(xi+x,-yi+y,mode); //7区
   draw(yi+x,-xi+y,mode); //8区
   if(dd<0) //D在圆内;H在圆上或圆外;选择H或D,dh>=0,dd<0,m=|dh|-|dd|=2*(dd+yi)-1;
   {
    m=2*(dd+yi)-1;
    if(m<=0) //取右像素H(xi+1,yi);m=0时 取右点
    {
     dd=dd+2*xi+3; //求H的右下像素(xi+2,yi-1),dd=(xi+2)*(xi+2)+(yi-1)*(yi-1)-R*R
     xi=xi+1;
    }
    else //取右下像素D(xi+1,yi-1)
    {
     dd=dd+2*(xi-yi+3); //求D的右下像素(xi+2,yi-2),dd=(xi+2)*(xi+2)+(yi-2)*(yi-2)-R*R
     xi=xi+1;
     yi=yi-1;
    }
   }
   else if(dd>0) //D在圆外;V在圆外或圆上;选择D或V;dd>0,dv<=0,n=|dd|-|dv|=2*(dd-xi)-1;
   {
    n=2*(dd-xi)-1;
    if(n<=0) //取右下像素D(xi+1,yi-1);n=0时取
    {
     dd=dd+2*(xi-yi+3); //求D的右下像素(xi+2,yi-2),dd=(xi+2)*(xi+2)+(yi-2)*(yi-2)-R*R
     xi=xi+1;
     yi=yi-1;
    }
    else //取下像素V(xi,yi-1)
    {
     dd=dd-2*yi+3; //求V的右下像素(xi+1,yi-2)dd=(xi+1)*(xi+1)+(yi-2)*(yi-2)-R*R
     yi=yi-1;
   
    }
   }
   else if(dd==0) //D在圆上,取D(xi+1,yi-1)
   {
    dd=dd+2*(xi-yi+3); //求D的右下像素(xi+2,yi-2),dd=(xi+2)*(xi+2)+(yi-2)*(yi-2)-R*R
    xi=xi+1;
    yi=yi-1;
   }
}
}

void ellipse(int x0, int y0, int rx, int ry,int mode) {
  int OutConst, Sum, SumY;
  int x,y;
  int xOld;
  uint32_t _rx = rx;
  uint32_t _ry = ry;
  OutConst = _rx*_rx*_ry*_ry  /* Constant as explaint above */
            +(_rx*_rx*_ry>>1); /* To compensate for rounding */
  xOld = x = rx;
  for (y=0; y<=ry; y++) {
    if (y==ry) {
      x=0;
    } else {
      SumY =((int)(rx*rx))*((int)(y*y)); /* Does not change in loop */
      while (Sum = SumY + ((int)(ry*ry))*((int)(x*x)),
             (x>0) && (Sum>OutConst)) x--;
    }
    /* Since we draw lines, we can not draw on the first
        iteration
    */
    if (y) {
      line(x0-xOld,y0-y+1,x0-x,y0-y,mode);
      line(x0-xOld,y0+y-1,x0-x,y0+y,mode);
      line(x0+xOld,y0-y+1,x0+x,y0-y,mode);
      line(x0+xOld,y0+y-1,x0+x,y0+y,mode);
    }
    xOld = x;
  }
}

一周热门 更多>