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;
}
}
{
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);//扫描线填充其量
}
}
}
你这个draw函数的底层是干什么的?还有mode?
知道半径R,知道圆心坐标,那就可以算出四分之一圆的坐标,通过跟圆心坐标的加减换算,可以得出上半圆的坐标,然后分别与圆心换算,得出下半圆的坐标,并每个上下坐标画垂直线。
也可以左右画线,看LCD驱动哪个实现起来更高速
就是在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;
}
}
一周热门 更多>