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

2020-1-15 10:02 2408 12 12 分类: MCU/ 嵌入式 文集: 程序设计

以下分不同象限分别给出算法,便于各位理解。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
#include
#include
#include
#include
#include
 
#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();
 
}
 
}

————————————————
版权声明:本文为CSDN博主「信雪神话」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hookie1990/article/details/45024049

文章评论0条评论)

登录后参与讨论
我要评论
0
12
关闭 站长推荐上一条 /2 下一条