3576|3

7228

帖子

192

TA的资源

五彩晶圆(高级)

楼主
 

【LCD12864学习】第8篇任意直线 [复制链接]

本帖最后由 常见泽1 于 2014-12-15 22:37 编辑

LCD12864 GUI学习
8 画任意线段
From EE: 常见泽
(刚换了工作,都忘记这一篇还没发,发出来大家看看把)
1. 原理图引脚(msp430g2452)
EN   —— P2.0
RS  —— P2.1
PSB —— P2.2
RW  —— P2.3

2.  Breshenham算法
基本上Bresenham画线算法的思路如下:
// 假设该线段位于第一象限内且斜率大于0小于1,设起点为(x1,y1),终点为(x2,y2).
// 根据对称性,可推导至全象限内的线段.
1.画起点(x1,y1).
2.准备画下个点。x坐标增1,判断如果达到终点,则完成。否则,由图中可知,下个要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点.
2.1.如果线段ax+by+c=0与x=x1+1的交点的y坐标大于M点的y坐标的话,下个点为U(x1+1,y1+1)
2.2.否则,下个点为B(x1+1,y1)
3.画点(U或者B).
4.跳回第2步.
5.结束
.
这里需要细化的是怎么判断下个要画的点为当前点的右邻接点还是当前点的右上邻接点.
设线段方程:ax+by+c=0(x1 令dx=x2-x1,dy=y2-y1
则:斜率-a/b= dy/dx.
从第一个点开始,我们有F(x,1,y1) = a*x1+b*y1+c=0
下面求线段ax+by+c=0与x=x1+1的交点:
由a*(x1+1)+b*y+c= 0, 求出交点坐标y=(-c-a(x1+1))/b
所以交点与M的y坐标差值Sub1 = (-c-a(x1+1))/b - (y1+0.5) = -a/b-0.5,即Sub1的处始值为-a/b-0.5。
则可得条件当 Sub1 = -a/b-0.5>0时候,即下个点为U.
反之,下个点为B.
代入a/b,则Sub1 = dy/dx-0.5.
因为是个循环中都要判断Sub,所以得求出循环下的Sub表达式,我们可以求出Sub的差值的表达式.下面求x=x1+2时的Sub,即Sub2
1.如果下下个点是下个点的右上邻接点,则
Sub2 = (-c-a(x1+2))/b - (y1+1.5) = -2a/b - 1.5
故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 1.5 -(-a/b-0.5) = -a/b - 1.代入a/b得Dsub = dy/dx -1;
2.如果下下个点是下个点的右邻接点,
Sub2 = (-c-a(x1+2))/b - (y1+0.5) = -2a/b - 0.5
故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 0.5 -(-a/b-0.5) = -a/b. 代入a/b得Dsub = dy/dx;
于是,我们有了Sub的处始值Sub1 = -a/b-0.5 = dy/dx-0.5,又有了Sub的差值的表达式Dsub = dy/dx -1 (当Sub1 > 0)或 dy/dx(当Sub1 < 0).细化工作完成。

3. 程序介绍

(代码也是改编的ZLG GUI的,具体里面的细节还要读者自己去研究了,我也是大概看懂了,会修改)
  1. void  GUI_Line(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1)
  2. {  unsigned int   dx;                                                // 直线x轴差值变量
  3.    unsigned int   dy;                                  // 直线y轴差值变量
  4.    unsigned char    dx_sym;                                        // x轴增长方向,为-1时减值方向,为1时增值方向
  5.    unsigned char    dy_sym;                                        // y轴增长方向,为-1时减值方向,为1时增值方向
  6.    unsigned int   dx_x2;                                        // dx*2值变量,用于加快运算速度
  7.    unsigned int   dy_x2;                                        // dy*2值变量,用于加快运算速度
  8.    unsigned int   di;                                                // 决策变量
  9.    
  10.    
  11.    dx = x1-x0;                                                // 求取两点之间的差值
  12.    dy = y1-y0;
  13.    
  14.    /* 判断增长方向,或是否为水平线、垂直线、点 */
  15.    if(dx>0)                                                        // 判断x轴方向
  16.    {  dx_sym = 1;                                        // dx>0,设置dx_sym=1
  17.    }
  18.    else
  19.    {  if(dx<0)
  20.       {  dx_sym = -1;                                // dx<0,设置dx_sym=-1
  21.       }
  22.       else
  23.       {  // dx==0,画垂直线,或一点
  24.          GUI_RLine(x0, y0, y1);
  25.                return;
  26.       }
  27.    }
  28.    
  29.    if(dy>0)                                                        // 判断y轴方向
  30.    {  dy_sym = 1;                                        // dy>0,设置dy_sym=1
  31.    }
  32.    else
  33.    {  if(dy<0)
  34.       {  dy_sym = -1;                                // dy<0,设置dy_sym=-1
  35.       }
  36.       else
  37.       {  // dy==0,画水平线,或一点
  38.          GUI_HLine(x0, y0, x1);
  39.                return;
  40.       }
  41.    }
  42.    /* 将dx、dy取绝对值 */
  43.    dx = dx_sym * dx;
  44.    dy = dy_sym * dy;
  45.    /* 计算2倍的dx及dy值 */
  46.    dx_x2 = dx*2;
  47.    dy_x2 = dy*2;
  48.    
  49.    /* 使用Bresenham法进行画直线 */
  50.    if(dx>=dy)                                                // 对于dx>=dy,则使用x轴为基准
  51.    {  di = dy_x2 - dx;
  52.       while(x0!=x1)
  53.       {  DrawPoint(x0, y0,1);
  54.          x0 += dx_sym;
  55.          if(di<0)
  56.          {  di += dy_x2;                        // 计算出下一步的决策值
  57.          }
  58.          else
  59.          {  di += dy_x2 - dx_x2;
  60.             y0 += dy_sym;
  61.          }
  62.       }
  63.       DrawPoint(x0, y0, 1);                // 显示最后一点
  64.    }
  65.    else                                                                // 对于dx<dy,则使用y轴为基准
  66.    {  di = dx_x2 - dy;
  67.       while(y0!=y1)
  68.       {  DrawPoint(x0, y0, 1);
  69.          y0 += dy_sym;
  70.          if(di<0)
  71.          {  di += dx_x2;
  72.          }
  73.          else
  74.          {  di += dx_x2 - dy_x2;
  75.             x0 += dx_sym;
  76.          }
  77.       }
  78.       DrawPoint(x0, y0, 1);                // 显示最后一点
  79.    }
  80. }
复制代码

4. 显示

最新回复

这个是不是只能并行使用12864?  详情 回复 发表于 2015-7-29 19:43

赞赏

1

查看全部赞赏

 
点赞 关注(4)

回复
举报

2万

帖子

74

TA的资源

管理员

沙发
 
谢谢分享  继续加油
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 

回复

1万

帖子

25

TA的资源

裸片初长成(高级)

板凳
 
点阵式LCD与TFT的驱动芯片有所不同,写一个字节的RAM就代表8个点,我现在正在考虑使用点阵式LCD实现象示波器的显示功能。
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

4
 
这个是不是只能并行使用12864?
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表