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的圆弧在这里插入图片描述
已知圆心(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<r ^2,此时实际点离(a+i+1,b+r-j-1)更近.
(x-a) ^2+ (y-b) ^2<r ^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++;	
	}
}
  • 9
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
STM32是一款非常流行的嵌入式微控制器系列,它具有强大的性能和丰富的外设资源。在学习STM32时,掌握如何进行Flash读写是非常重要的。 Flash是一种非易失性存储器,可以用来存储程序代码和数据。在STM32中,Flash存储器通常用来存储应用程序代码。下面是一个简单的Flash读写程序的示例: 1.首先,我们需要包含适用于所使用的STM32型号的头文件。例如,对于STM32F4系列,我们需要包含"stm32f4xx.h"。 2.然后,我们需要定义一个指向Flash存储器的指针变量。例如,可以使用如下代码:`uint32_t* flash_address = (uint32_t*)0x08000000;`其中0x08000000是Flash存储器的起始地址。 3.要读取Flash存储器中的数据,我们可以通过以下代码实现:`data = *flash_address;`其中data是一个变量,用于存储读取到的数据。 4.要写入数据到Flash存储器中,我们可以通过以下代码实现:`*flash_address = data;`其中data是要写入的数据。 需要注意的是,STM32的Flash存储器是有写保护机制的,因此在写入数据之前,我们需要禁用写保护。可以使用以下代码禁用写保护:`FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB;`然后才能进行数据写入。 另外,为了确保数据的完整性,我们可以使用CRC校验来验证Flash存储器中的程序代码的正确性。可以使用库函数来计算校验和,然后将其与预期的校验和进行比较以进行验证。 综上所述,掌握STM32的Flash读写操作对于嵌入式系统的开发非常重要。上述示例代码可以帮助我们快速进行Flash读写操作,同时注意写保护和数据校验可以提高数据的安全性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值