项目简介

屏幕作为人机交互形式之一,复杂的已有GUI支持和各种样式。而在一些较简单的应用当中,则可以采用画线画点的方式去实现。本次带来的是 Bresenham算法在屏幕上实现画任意线的应用。

项目详情

1、Bresenham算法简介

直线方程:

最基本的斜截式直线方程为y=kx+b(k为斜率,b为截距)y=kx+b(k为斜率,b为截距)。这个方程存在的缺点是无法表示直线x=αx=α,所以用一个新的方程来代替Ax+By+C=0Ax+By+C=0。

Bresenham

Bresenham画直线的算法主要步骤是判断下一点的位置。维基百科中有一张图比较形象:

图中,每一个点代表的是一个像素,假定我们有直线f(x,y)f(x,y)且当前坐标为(x,y)(x,y),判断下一个点的y轴坐标步骤为(如果要确定x轴坐标也类似):

算法详情请点击链接

2、开发板实现

2.1 开发板型号:兆易创新GD32VF103V-EVAL全功能开发板

2.2 使用IDE:NucleiStudio_IDE_201909

2.3 新建工程:请参考GD32官方提供的开发板例程,新建一个简单的工程 ----- 编译下载一次确保能成功

2.4 开始修改工程:

由于NucleiStudio新建一个完整的工程后,自带的TFT代码是旧版本,所以第一步直接替换掉以下这两个文件;回到软件刷新一下工程

在main.c中添加头文件以及初始化TFT液晶,来个清屏,看看能否使用

2.5 将Bresenham算法函数代码移植好,修改函数中的画点函数使之对应自己的开发板,代码如下

/*

-------------------------------------------------------------------------------------------

@函数功能 :画任意线 Bresenham算法函数

@ @ x0 : 屏幕x轴开始

@ @ y0 : 屏幕y轴开始

@ @ x1 : 屏幕x轴结束

@ @ y1 : 屏幕y轴结束

@ @ color : 线的颜色

-------------------------------------------------------------------------------------------

*/

#define SWAP(a, b) {int t = a; a = b; b = t;} //量值的交换

static void Write_IntBresenhamline(int x0, int y0, int x1, int y1, int color){

// ................................... // 画任意线Bresenham算法函数

int dx = x1 - x0, //获取X长度

dy = y1 - y0; //获取Y长度

if(abs(dx) >= abs(dy)) //取绝对值 区分象限

{

if(x0 > x1) //xy坐标反向

{

SWAP(x0, x1); SWAP(y0, y1);//交换

dx = -dx; dy = -dy; //取正

}

if(dy >= 0) // 直线的倾斜角位于 [0, pi / 4]

{

for(int x = x0, y = y0, e = -dx; x <= x1; x ++)

{

lcd_point_set(x,y,color);//快速画点

e += dy * 2;

if(e >= 0){

y ++;

e -= dx * 2;

}

}

}else // 直线的倾斜角位于 [-pi / 4, 0)

{

for(int x = x0, y = y0, e = dx; x <= x1; x ++)

{

lcd_point_set(x,y,color);//快速画点

e+= dy * 2;

if (e <= 0){

y --;

e += dx * 2;

}

}

}

}else

{

if(y0 > y1) //xy坐标反向

{

SWAP(x0, x1); SWAP(y0, y1); //交换

dx = -dx; dy = -dy; //取正

}

if(dx >= 0) // 直线的倾斜角位于 (pi / 4, pi / 2]

{

for(int x = x0, y = y0, e = -dy; y <= y1; y ++)

{

lcd_point_set(x,y,color);//快速画点

e += dx * 2;

if(e >= 0){

x ++;

e -= dy * 2;

}

}

}

else // 直线的倾斜角位于 [-pi / 2, -pi / 4)

{

for(int x = x0, y = y0, e = dy; y <= y1; y ++)

{

lcd_point_set(x,y,color);//快速画点

e += dx * 2;

if (e <= 0){

x --;

e += dy * 2;

}

}

}

}

}

2.6 在主函数直接调用该函数即可,如下

switch(i)

{

case 0:Write_IntBresenhamline(0, 0, 239, 319,LCD_COLOR_RED);break;

case 1:Write_IntBresenhamline(239, 0, 0, 319,LCD_COLOR_GREEN);break;

case 2:Write_IntBresenhamline(0, 160, 319,160, LCD_COLOR_BLUE);break;

case 3:Write_IntBresenhamline(10, 134, 156,180, LCD_COLOR_WHITE);break;

case 4:Write_IntBresenhamline(18, 240, 46,90, LCD_COLOR_CYAN);break;

case 5:Write_IntBresenhamline(67, 88, 123,245, LCD_COLOR_BLUE2);break;

case 6:Write_IntBresenhamline(54, 34, 72,10, LCD_COLOR_YELLOW);break;

case 7:Write_IntBresenhamline(120, 300, 200,120, LCD_COLOR_MAGENTA);break;

case 8:i=0;break;

}

i++;

项目实测效果

展开阅读全文