1.如何画点
给定地址,往地址发送RGB数据。
BACK_COLOR=White;//选择背景色
POINT_COLOR=Black;//选择画笔颜色
Lcd_DrawPoint(int x,int y);//画个点
2.如何画圆
点阵屏画圆需要进行一些判断的,因为三角函数算出的值并不能很完美的点亮。所以需要别的方法,也就是适应点阵屏的点亮方式。
根据圆的对称性,我们只需要画出1/8圆就行,然后镜像,分别是关于y=0.5x这根轴的镜像填补一个象限,再关于xy轴,圆心填补所有象限。
Bresenham画圆法:
/*圆心(0,0) 半径r=10
选定起始点(0,10)
移动x坐标右移,按照圆的形状规则,此时会有三个选择点产生:
u(x+1,y) :上一点u
d(x+1,y-1):下一点d
l(x+1,y-0.5):按照圆规则应该点亮此点,但是液晶像素没办法点亮半个,此时只能选择上一点u或者下一点d。
j=lx^2+ly^2-r^2=0;将l点放入此公式,
j>0:圆的下一点选择u
j<0:圆的下一点选择d
j=0:按照约定选择u
一直选择到x<=y
在算法中多一个点就会多耗费一点资源,我们优化一下算法:
Di=Du+Dd=(x+1)^2+y^2+(x+1)^2+(y-1)^2-2r^2
化简此公式:
初始态:x=0,y=r,di=3-2r,所以就有了下面的函数
也就是经典的Bresenham画圆法。
*/
//这个是液晶通用的画圆函数
/**
* @brief 画一个圆
*
* @param x0,y0 圆心坐标
* @param r 圆半径
*
* @return void
*/
void LCD_Draw_Circle(uint16_t x0, uint16_t y0, uint8_t r)
{
int a, b;
int di;
a = 0;//x偏移变量
b = r;//y偏移变量
di = 3 - (r << 1);//判别式(x+1)^2+y^2+(x+1)^2+(y-1)^2-2r^2,x=0,y=r代入此公式
while(a <= b)
{
//这几个都是镜像点,初始点为(x,y+r)
LCD_Draw_Point(x0 - b, y0 - a);
LCD_Draw_Point(x0 + b, y0 - a);
LCD_Draw_Point(x0 - a, y0 + b);
LCD_Draw_Point(x0 - b, y0 - a);
LCD_Draw_Point(x0 - a, y0 - b);
LCD_Draw_Point(x0 + b, y0 + a);
LCD_Draw_Point(x0 + a, y0 - b);
LCD_Draw_Point(x0 + a, y0 + b);
LCD_Draw_Point(x0 - b, y0 + a);
a++;
if(di < 0)di += 4 * a + 6;//更新判别式 ,选择u点xi=x+1 yi=y
else
{
di += 10 + 4 * (a - b);//更新判别式,选择d点xi=x+1 yi=y+1
b--;
}
LCD_Draw_Point(x0 + a, y0 + b);
}
}
3.如何画直线,也是Bresenham
同样使用此法:
求直线斜率:k=y/x
起始点(x,y),那么下一点有两个选择:
u(x+1,y)
d(x+1,y+1)
di+=k;di初始为0;
如果di>1,令di=0;一直到x轴直线的终点位置。
di>0.5;选直线下一点为u,
di<0.5;选直线上一点d
di=0.5:选择预定u