LCD圆弧绘制算法~基于逐点比较算法,入口参数:弧线起点、终点(逆时针方向)、圆心


以下分不同象限分别给出算法,便于各位理解。area1即为第一象限,依次类推。

/************************圆弧插补算法
    液晶坐标系统如下:
    0------->x
    |
    |
    |
    y
    调用实例如下:
    arc_chabu_area1(120,340,120,275,180,340);    
    arc_chabu_area2(415,145,390,110,415,100);
    arc_chabu_area3(250,225,250,275,200,225);
    arc_chabu_area4(250,225,300,225,250,275);
    
    注意:调用弧线的起始和终点按逆时针方向
                                                          
******************************************/
void arc_chabu_area1(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2)
{
    
    u16 x,y,xi,yi;
    u8 e;
    x=xi=x2;
    y=yi=y2;
    POINT_COLOR=GRAY;
    e=abs(x2-x1)+abs(y2-y1);
    while(e!=0)
    {
        if(fi1>=0)
        {
             x=xi-1;
             fi1=fi1+2*(x0-xi)+1;
            LCD_DrawLine(xi,yi,x,y,5);
             xi=x;
             e--;
        }
        else
        {
            y=yi-1;
            fi1=fi1+2*(y0-yi)+1;
            LCD_DrawLine(xi,yi,x,y,5);
            yi=y;
            e--;
        }    
    }    

}

void arc_chabu_area2(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2)
{
    
    u16 x,y,xi,yi;
    u8 e;
    x=xi=x2;
    y=yi=y2;
    e=abs(x2-x1)+abs(y2-y1);
    while(e!=0)
    {
        if(fi2>=0)
        {
             y=yi+1;
             fi2=fi2+2*(yi-y0)+1;
            LCD_DrawLine(xi,yi,x,y,5);
             yi=y;
             e--;
        }
        else
        {
            x=xi-1;
            fi2=fi2+2*(x0-xi)+1;
            LCD_DrawLine(xi,yi,x,y,5);
            xi=x;
            e--;
        }    
    }    

}


void arc_chabu_area3(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2)
{
    
    u16 x,y,xi,yi;
    u8 e;
    x=xi=x2;
    y=yi=y2;
    e=abs(x2-x1)+abs(y2-y1);
    while(e!=0)
    {
        if(fi3>=0)
        {
             x=xi+1;
             fi3=fi3+2*(xi-x0)+1;
            LCD_DrawLine(xi,yi,x,y,5);
             xi=x;
             e--;
        }
        else
        {
            y=yi+1;
            fi3=fi3+2*(yi-y0)+1;
            LCD_DrawLine(xi,yi,x,y,5);
            yi=y;
            e--;
        }    
    }    

}

void arc_chabu_area4(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2)
{
    
    u16 x,y,xi,yi;
    u8 e;
    x=xi=x2;
    y=yi=y2;
    e=abs(x2-x1)+abs(y2-y1);
    while(e!=0)
    {
        if(fi4>=0)
        {
             y=yi-1;
             fi4=fi4+2*(y0-yi)+1;
            LCD_DrawLine(xi,yi,x,y,5);
             yi=y;
             e--;
        }
        else
        {
            x=xi+1;
            fi4=fi4+2*(xi-x0)+1;
            LCD_DrawLine(xi,yi,x,y,5);
            xi=x;
            e--;
        }    
    }    

}

如图中lcd的液晶上的弧线即通过该算法绘制


启动单片机UI绘制代码:

#include <STC12C5A60S2.h>
#include <font/font.h>
#include <lcd/lcd.h>
#include <sys/sys.h>
#include <touch/touch.h>
#include <math.h>

#define  uchar unsigned char 
#define  uint  unsigned int
#define  uchar unsigned char 
#define  uint  unsigned int


 


sbit RUN_LED = P1^0;  //运行指示灯

#define RUN_LED led1

u8 Rdate;//	串口接收到的数据


int fi1=0;
int fi2=0;
int fi3=0;
int fi4=0;





void touch_getdata()
{	 
 if (tpstate()==0) //如果触摸按下,则进入绘图程序
	 {
		BACK_COLOR=BLACK;
		POINT_COLOR=RED;
	 	point();
	 }    
}

void xianshi()//显示信息
{   
	BACK_COLOR=BLACK;
	POINT_COLOR=BLUE;	
	//showhanzi(10,0,0);  //以下汉字分别是:欢迎您使用智能智能机器人服务系统
	//showhanzi(45,0,1);  //
	//showhanzi(75,0,2);
	//showhanzi(105,0,3);
	//showhanzi(140,0,4);
	showhanzi(225,5,5);//智
	showhanzi(260,5,6);//能
	showhanzi(295,5,7);//机
	showhanzi(325,5,8);//器
	showhanzi(360,5,9);//人
	showhanzi(395,5,10);//服
	showhanzi(425,5,11);//务
	showhanzi(460,5,12);//系
	showhanzi(495,5,13);//统

//	LCD_ShowString(10,35,"hookie the best wishes to you! ");
//	LCD_ShowString(10,35,"HardWare Information:");
//	LCD_ShowString(205,45,"LCD_W:");	LCD_ShowNum(255,45,LCD_W,3);	  //已宏定义LCD_W和LCD_H 的数值
//	LCD_ShowString(300,45,"LCD_H:");LCD_ShowNum(350,45,LCD_H,3);	
//	lx=400;ly=45;			
//	LCD_ShowString(lx,ly,"VX:");lx+=40;LCD_ShowNum(lx,ly,vx,5);					
//	lx+=60;
//	LCD_ShowString(lx,ly,"Vy:");lx+=40;LCD_ShowNum(lx,ly,vy,5);					

}

/********************************************* 
在指定位置处显示60*60像素的图片
其他像素要自己判断距离

**********************************************/
void show_image(u16 startx,u16 starty,u16 endx,u16 endy)
{
	unsigned int i; 
	Address_set(startx,starty,endx,endy);		//坐标设置
    for(i=0;i<3600;i++)
	 { 	
 
	  	 LCD_WR_DATA8(image[i*2+1],image[i*2]);	 //发送颜色数据为提高速度高8位低8位分别传递
		 	   						
	 }

}


/************************圆弧插补算法
	液晶坐标系统如下:
	0------->x
	|
	|
	|
	y
	调用实例如下:
	arc_chabu_area1(120,340,120,275,180,340);	
	arc_chabu_area2(415,145,390,110,415,100);
	arc_chabu_area3(250,225,250,275,200,225);
	arc_chabu_area4(250,225,300,225,250,275);
	
	注意:调用弧线的起始和终点按逆时针方向。
		参数说明:	x0,y0圆心坐标。
					x1,y1起点坐标。
					x2,y2终点坐标。
  														
******************************************/
void arc_chabu_area1(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2,u8 width,u16 point_color)
{
	
	u16 x,y,xi,yi,color;
	u8 e;
	color=POINT_COLOR;
	POINT_COLOR=point_color;
	x=xi=x2;
	y=yi=y2;
	e=abs(x2-x1)+abs(y2-y1);
	while(e!=0)
	{
		if(fi1>=0)
		{
		 	x=xi-1;
		 	fi1=fi1+2*(x0-xi)+1;
			LCD_DrawLine(xi,yi,x,y,width);
		 	xi=x;
		 	e--;
		} 
		else
		{
			y=yi-1;
			fi1=fi1+2*(y0-yi)+1;
			LCD_DrawLine(xi,yi,x,y,width);
			yi=y;
			e--;
		}	
	}
	
	POINT_COLOR=color;	

}

void arc_chabu_area2(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2,u8 width,u16 point_color)
{
	
	u16 x,y,xi,yi,color;
	u8 e;
	color=POINT_COLOR;
	POINT_COLOR=point_color;
	x=xi=x2;
	y=yi=y2;
	e=abs(x2-x1)+abs(y2-y1);
	while(e!=0)
	{
		if(fi2>=0)
		{
		 	y=yi+1;
		 	fi2=fi2+2*(yi-y0)+1;
			LCD_DrawLine(xi,yi,x,y,width);
		 	yi=y;
		 	e--;
		} 
		else
		{
			x=xi-1;
			fi2=fi2+2*(x0-xi)+1;
			LCD_DrawLine(xi,yi,x,y,width);
			xi=x;
			e--;
		}	
	}
	
	POINT_COLOR=color;	

}


void arc_chabu_area3(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2,u8 width,u16 point_color)
{
	
	u16 x,y,xi,yi,color;
	u8 e;

	color=POINT_COLOR;
	POINT_COLOR=point_color;

	x=xi=x2;
	y=yi=y2;
	e=abs(x2-x1)+abs(y2-y1);
	while(e!=0)
	{
		if(fi3>=0)
		{
		 	x=xi+1;
		 	fi3=fi3+2*(xi-x0)+1;
			LCD_DrawLine(xi,yi,x,y,width);
		 	xi=x;
		 	e--;
		} 
		else
		{
			y=yi+1;
			fi3=fi3+2*(yi-y0)+1;
			LCD_DrawLine(xi,yi,x,y,width);
			yi=y;
			e--;
		}	
	}
	
	POINT_COLOR=color;	

}

void arc_chabu_area4(u16 x0,u16 y0,u16 x1,u16 y1,u16 x2,u16 y2,u8 width,u16 point_color)
{
	
	u16 x,y,xi,yi,color;
	u8 e;
	color=POINT_COLOR;

	POINT_COLOR=point_color;

	x=xi=x2;
	y=yi=y2;
	e=abs(x2-x1)+abs(y2-y1);
	while(e!=0)
	{
		if(fi4>=0)
		{
		 	y=yi-1;
		 	fi4=fi4+2*(y0-yi)+1;
			LCD_DrawLine(xi,yi,x,y,width);
		 	yi=y;
		 	e--;
		} 
		else
		{
			x=xi+1;
			fi4=fi4+2*(xi-x0)+1;
			LCD_DrawLine(xi,yi,x,y,width);
			xi=x;
			e--;
		}	
	}

	POINT_COLOR=color;	

}

void draw_map()
{
//信息及框架
	xianshi();
	show_image(50,90,109,149);
	POINT_COLOR=GRAY;
	LCD_DrawRectangle(2,2,798,480,2);//边框
	POINT_COLOR=BLUE;
	LCD_DrawRectangle(25,50,775,430,2);//地图绘制区域
	//LCD_DrawLine(25,240,775,240,1);
	//LCD_DrawLine(375,50,375,430,1);
	LCD_DrawRectangle(150,450,250,475,1);
	LCD_DrawRectangle(550,450,650,475,1);
	LCD_DrawRectangle(350,450,450,475,1);
	POINT_COLOR=RED;
	LCD_ShowString(185,455,"MIN");
	LCD_ShowString(585,455,"MAX");
	LCD_ShowString(385,455,"SEND");
    LCD_ShowString(420,70,"Tip Information:");
	LCD_ShowString(570,70,"wait operation");

/***************开始绘制实际地图********************/
	lcd_draw_route_line(35,225,200,225);
	Draw_Circle_big(250,225,50,WHITE);
	
	//POINT_COLOR=GRAY;
	LCD_Fill(35,170,120,215,GRAY); //传达室
	Draw_Circle_big(75,205,8,GREEN);

    LCD_Fill(35,275,120,340,GRAY);	//理苑
	LCD_Fill(120,340,185,420,GRAY);	//理苑
	arc_chabu_area1(120,340,120,275,180,340,5,GRAY);	//2区域弧线
	arc_chabu_area1(120,340,120,285,170,340,5,GRAY);	//2区域弧线
   	arc_chabu_area1(120,340,120,295,160,340,5,GRAY);	//2区域弧线
	arc_chabu_area1(120,340,120,305,150,340,5,GRAY);	//2区域弧线
	arc_chabu_area1(120,340,120,315,140,340,5,GRAY);	//2区域弧线
   	arc_chabu_area1(120,340,120,325,130,340,5,GRAY);	//2区域弧线

	  
	LCD_Fill(150,80,235,165,GRAY);	//后勤
	LCD_Fill(470,110,530,175,GRAY); //dianxin
	
	LCD_Fill(435,165,530,210,GRAY); //dianxin
	LCD_Fill(530,140,670,190,GRAY);//dianxin
	LCD_Fill(520,150,655,170,BLACK);
	LCD_Fill(590,110,720,190,GRAY);//jidian

	LCD_Fill(350,250,460,310,GRAY);//shengming
	LCD_Fill(460,250,500,380,GRAY);//
	LCD_Fill(500,290,700,380,GRAY);
	LCD_Fill(415,340,460,380,GRAY);
	LCD_Fill(290,340,390,370,GRAY);
	LCD_Fill(390,340,415,420,GRAY);
	LCD_Fill(290,400,390,420,GRAY);
	LCD_Fill(500,320,665,360,BLACK);
	
	

	
	//arc_chabu_area3(250,225,250,275,200,225);//第三象限弧线绘制测试语句
	//arc_chabu_area4(250,225,300,225,250,275,2,BLACK);  //第四象限弧线绘制测试语句
	arc_chabu_area2(415,145,390,110,415,100,5,WHITE);	 //4区域上弧线
	lcd_draw_route_line(415,100,680,100);
	lcd_draw_route_line(560,100,560,120);
	Draw_Circle_big(560,120,8,GREEN);

	arc_chabu_area4(680,60,700,90,680,100,5,WHITE);	//you shang huxian
	lcd_draw_route_line(700,95,750,60);
	lcd_draw_route_line(570,200,570,220);
	Draw_Circle_big(570,205,8,GREEN);
	

	lcd_draw_route_line(300,225,740,225);
	lcd_draw_route_line(520,225,520,275);
	Draw_Circle_big(520,270,8,GREEN);
	lcd_draw_route_line(740,225,740,400);
	lcd_draw_route_line(740,225,760,140);



	
	arc_chabu_area2(470,225,410,225,435,165,5,WHITE);	//4区域下弧线
	Draw_Circle_big(435,165,8,GREEN);


	lcd_draw_route_line(590,400,740,400);
	arc_chabu_area1(350,125,350, 80,390,110,5,WHITE);	//3区域弧线
	arc_chabu_area2(590,430,560,420,590,400,5,WHITE);	//9区域弧线
	lcd_draw_route_line(430,400,550,400);
	Draw_Circle_big(430,400,8,GREEN);  //5
	lcd_draw_route_line(570,405,520,390);
	Draw_Circle_big(520,390,8,GREEN);



	lcd_draw_route_line(180,290,215,260);
	Draw_Circle_big(180,290,8,GREEN);
	lcd_draw_route_line(250,415,250,275);
	
	lcd_draw_route_line(290,190,390,110);

	lcd_draw_route_line(350,83,250,83);
	lcd_draw_route_line(250,83,250,120);
	Draw_Circle_big(250,120,8,GREEN);
	
	
	lcd_draw_route_line(250,380,370,380);
	Draw_Circle_big(370,380,8,GREEN);




}




void main()
{
	//EA=1;
	//ES=1;
	beep=1;//CLOSE BEEP

	spistar()  ;//模拟SPI初始化

	
	Lcd_Init();   //tft初始化
	uart_init();

	LCD_Clear(BLACK); //清屏

	draw_map();
	while(1)
	{
	keyscan();
	touch_getdata();

	}

}


原文地址:https://www.cnblogs.com/siahekai/p/11000836.html