STM32学习笔记-LCD画直线,画圆

STM32学习笔记-LCD画直线,画圆
1.画直线
如果在两点(a,b)(c,d)之间画直线,首先考虑c>a,d>b,且k<1的情况,其他情况根据对称关系就能推导出来了。
为了使问题简单化,先将这两点进行平移,将(a,b)平移到原点,那么(c,d)变换后的坐标就是(e,f),其中e=c-a,f=d-b,斜率k=f/e;
假设在LCD上我们取的第i个像素点的坐标是(i,j),那么第i+1个像素点的坐标应该是(i+1,j)或者(i+1,j+1),到底取那个点,我们就需要判定这两个点离哪个点距离实际点(i+1,(i+1)*k)更近
(i+1,j)与(i+1,(i+1)*k)距离S1=(i+1)*k-j
(i+1,j+1)与(i+1,(i+1)*k)距离S2=j+1-(i+1)k
设S1>S2
(i+1)k-j>j+1-(i+1)k
2
(i+1)k>2j+1
将k=f/e,代入
2
(i+1)f/e>2j+1
2
(i+1)f>(2j+1)*e //根据第i点来推测i+1个点位置的判别式

    i=0;j=0;//初始点
    for(i=0;i<e+1;i++)
	{	 		
	   if(e*(2*j+1)<2*f*(i+1))//根据当前点的位置来推测下一个点的位置
	  {
		j++; //像素点(i+1,j+1)距离实际点(i+1,(i+1)*k)更近
	  }		
    }

根据上述代码我们就得到(0,0)到(e,f)的所有点,其他情况可以根据对称性得到,以下为所有情况的代码

void drawline(u32 a,u32 b,u32 c,u32 d,u16 color)
{
	u32 e,f,i,j,g,flag;//flag为两点之间状态标志位
	flag=0;
	if(c>a)
	{
	  e=c-a;
	}
	else
	{
	  e=a-c;
	  flag|=0x01;
	}
	if(d>b)
	{		
	 f=d-b;
	}
	else
	{
	 f=b-d;
	 flag|=0x02;
	}
	if(f>e)//当画线斜率大于1时,
	{
		g=f;
		f=e;
		e=g;
		flag|=0x04;
	}
	j=0;	
	for(i=0;i<e+1;i++)
	{	
       switch(flag&0x07)
	  {
       	case 0:LCD_dpoint(a+i,b+j,color); break; //画点时要将坐标平移回来
		case 1:LCD_dpoint(a-i,b+j,color); break;
		case 2:LCD_dpoint(a+i,b-j,color); break;
		case 3:LCD_dpoint(a-i,b-j,color); break;
		case 4:LCD_dpoint(a+j,b+i,color); break;
	    case 5:LCD_dpoint(a-j,b+i,color); break;
		case 6:LCD_dpoint(a+j,b-i,color); break;
		case 7:LCD_dpoint(a-j,b-i,color); break;
		default:break;
	  }			 		
	  if(e*(2*j+1)<2*f*(i+1))//根据当前点的位置来推测下一个点的位置
	 {
		j++;
	 }		
	}
}

2.画圆
画圆的方法与画直线的方法类似,也是根据第i个点的坐标来推测i+1个点的坐标,因为圆的对称性,只需要画1/8圆即可,只需要画出从A到B的圆弧STM32学习笔记-LCD画直线,画圆_第1张图片
已知圆心(a,b)与半径r,横坐标变化量i,纵坐标变化量j,A点坐标为(a,b+r)
第i个像素点的坐标为(a+i,b+r-j) 第i+1像素点的坐标就是(a+i+1,b+r-j)或者是(a+i+1,b+r-(j+1)),我们需要判断那个点离实际点更近。我们可以首先求出这两个像素点的中点C(x,y)其中x=(2a+2i+1)/2,y=(2b+2r-2j-1)/2,当中点C在圆外时(x-a) ^2+ (y-b) ^2>r ^2,此时实际点离(a+i+1,b+r-j)更近,当中点C在圆内时(x-a) ^2+ (y-b) ^2 (x-a) ^2+ (y-b) ^2 4*(i+1)(i+1)+(2r-2j+1)(2r-2j+1)<4rr
停止点B坐标满足的条件为i+j=r,但实际仅设置这个条件可能不行还需要加上条件i+j+1;

	i=j=0;
	while((i+j!=r)&&(i+j!=r+1))
	{	
		if(4*(i+1)*(i+1)+(2*r-2*j+1)*(2*r-2*j+1)>4*r*r)
		{
			j++;
		}		
		i++;	
	}

这样就得到了所有点,再根据对称性得到其他部分圆弧,以下为实现代码

void draw_circle(u32 a,u32 b,u32 r,u16 color)
{
	u32 i,j;
	i=j=0;
	while((i+j!=r)&&(i+j!=r+1))
	{	
		LCD_dpoint(a+i,b+r-j,color);
		LCD_dpoint(a+i,b-r+j,color);
		LCD_dpoint(a-i,b+r-j,color);
		LCD_dpoint(a-i,b-r+j,color);
		
		LCD_dpoint(a+r-j,b+i,color);
		LCD_dpoint(a-r+j,b+i,color);
		LCD_dpoint(a+r-j,b-i,color);
		LCD_dpoint(a-r+j,b-i,color);
		if(4*(i+1)*(i+1)+(2*r-2*j+1)*(2*r-2*j+1)>4*r*r)
		{
			j++;
		}		
		i++;	
	}
}

你可能感兴趣的:(STM32)