野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14218|回复: 1

关于一个函数的实现,请前辈们帮忙指点

[复制链接]
发表于 2021-10-3 12:27:03 | 显示全部楼层 |阅读模式
本帖最后由 一级菜鸟 于 2021-10-3 12:55 编辑

这是霸道系列开发板的液晶驱动那节课的一个例程
例程中一个根据俩个坐标画线的函数,以下是例程中的原函数
  1. /**
  2. * [url=home.php?mod=space&uid=41770]@brief[/url]  在 ILI9341 显示器上使用 Bresenham 算法画线段
  3. * @param  usX1 :在特定扫描方向下线段的一个端点X坐标
  4. * @param  usY1 :在特定扫描方向下线段的一个端点Y坐标
  5. * @param  usX2 :在特定扫描方向下线段的另一个端点X坐标
  6. * @param  usY2 :在特定扫描方向下线段的另一个端点Y坐标
  7. * [url=home.php?mod=space&uid=87825]@note[/url] 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
  8. * @retval 无
  9. */
  10. void ILI9341_DrawLine ( uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2 )
  11. {
  12.         uint16_t us;
  13.         uint16_t usX_Current, usY_Current;
  14.         
  15.         int32_t lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance;
  16.         int32_t lIncrease_X, lIncrease_Y;         
  17.         
  18.         
  19.         lDelta_X = usX2 - usX1; //计算坐标增量
  20.         lDelta_Y = usY2 - usY1;
  21.         
  22.         usX_Current = usX1;
  23.         usY_Current = usY1;
  24.         
  25.         
  26.         if ( lDelta_X > 0 )
  27.                 lIncrease_X = 1; //设置单步方向
  28.         
  29.         else if ( lDelta_X == 0 )
  30.                 lIncrease_X = 0;//垂直线
  31.         
  32.         else
  33.   {
  34.     lIncrease_X = -1;
  35.     lDelta_X = - lDelta_X;
  36.   }

  37.         
  38.         if ( lDelta_Y > 0 )
  39.                 lIncrease_Y = 1;
  40.         
  41.         else if ( lDelta_Y == 0 )
  42.                 lIncrease_Y = 0;//水平线
  43.         
  44.         else
  45.   {
  46.     lIncrease_Y = -1;
  47.     lDelta_Y = - lDelta_Y;
  48.   }

  49.         
  50.         if (  lDelta_X > lDelta_Y )
  51.                 lDistance = lDelta_X; //选取基本增量坐标轴
  52.         
  53.         else
  54.                 lDistance = lDelta_Y;

  55.         
  56.         for ( us = 0; us <= lDistance + 1; us ++ )//画线输出
  57.         {  
  58.                 ILI9341_SetPointPixel ( usX_Current, usY_Current );//画点
  59.                
  60.                 lError_X += lDelta_X ;
  61.                 lError_Y += lDelta_Y ;
  62.                
  63.                 if ( lError_X > lDistance )
  64.                 {
  65.                         lError_X -= lDistance;
  66.                         usX_Current += lIncrease_X;
  67.                 }  
  68.                
  69.                 if ( lError_Y > lDistance )
  70.                 {
  71.                         lError_Y -= lDistance;
  72.                         usY_Current += lIncrease_Y;
  73.                 }
  74.                
  75.         }
复制代码
下面是我自己改写的函数,是根据两点法求直线的灵感来写的
自己写完感觉代码冗余量有点多,不过一个新手希望大家谅解。
希望各位前辈给予指导
  1. /*这里我就没有修改函数名,输入参数也是一样的*/
  2. void ILI9341_DrawLine(uint16_t usX1, uint16_t usY1,uint16_t usX2,uint16_t usY2)
  3. {
  4.    uint16_t i,j,n,Y,xmin,xmax,ymin,ymax;/*这里定义的变量有点多,i,j,n都是循环变量,Y是用来存放整型数据的Y坐标*/
  5.    n=0;/*n变量每次调用这个函数时初始化为0表示从0开始计数*/
  6.    double k,y;/*定义两个浮点型变量,k用来存放直线的斜率,y用来存放计算后的Y坐标*/
  7.    uint16_t X_Y[240*320][2] = {0};/*定义一个二维数组用来存放X,Y坐标,240*320是应为使用3.2寸的屏幕时像素点只有这么多,每次调用函数时数组初始化为空方便存入新的数据*/

  8.    /*下面两个if语句用来整理传入的X,Y坐标,方便下面计算*/
  9.    if(usX1>usX2)
  10.   {
  11.     xmax = usX1;
  12.     xmin = usX2;
  13.    }else{
  14.      xmax = usX2;
  15.      xmin = usX1;
  16.    }
  17.    if(usY1>usY2)
  18.   {
  19.     ymax = usY1;
  20.     ymin = usY2;
  21.    }else{
  22.      ymax = usY2;
  23.      ymin = usY1;
  24.    }   

  25.    /*根据两点式求出直线的斜率*/
  26.    k = (ymax - ymin) / (xmax - xmin);

  27.     /*遍历两点之间的所有X坐标,也可以改为遍历Y坐标*/
  28.    for(i=xmin;i<=xmax;i++)
  29.    {
  30.       y = k * (i - xmin) + ymin;/*根据斜率计算出Y坐标*/
  31.       Y = (uint16_t)y;/*此时Y坐标为浮点型,将他转换为整型数据存放在数组中*/
  32.       X_Y[n][] = {i,Y};/*把X,Y坐标存入数组*/
  33.       n++;
  34.    }

  35.   /*遍历存放坐标的数组*/  
  36.   for(j=0;j<n;j++)
  37.   {
  38.      ILI9341_SetPointPixel ( X_Y[j][0], X_Y[j][1] );/*这个函数的作用是根据坐标填充像素点,把数组中的X,Y坐标作为参数传入这个函数*/
  39.   }
  40. }
复制代码






回复

使用道具 举报

 楼主| 发表于 2021-10-3 12:54:13 | 显示全部楼层
y = k * (i - xmin) + ymin;
Y = (int)y;
  X_Y[n][] = {i,Y};
这里的Y=(uint16_t)y;是否可以省略
直接X_Y[n][] = {i,(uint16_t)y};
我印象中是不可以的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-28 04:38 , Processed in 0.031804 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表