最近在研究和制作数字示波器,其中涉及一个小算法:需要将 ADC 采样的数值在 TFT LCD 屏幕上面显示并且用“线”连接起来。

ADC 按照时序对输入电压采样后,记录的是一个个的数值,如果显示的时候不用“线”连接它们,那么他们看上去就是这样的:

用直线连接以后,看上去就是这样了(垃圾 LM324 运放的模拟前端,方波波形变形严重到令人发指):

X 轴(时间轴)的放大比率确定以后,ADC 采样值的相邻 2 点在屏幕上的间距也就确定了,连线算法要做的事情,就是将位于这两点间的直线上的 LCD 小点一个个点亮。

说实话,不是做数字示波器,我还真不太会用得到这个算法。我也没有查资料,直接就想到了“2分法”+ 递归来处理:

  1. 将起点(X1,Y1)和终点的坐标(X2,Y2)传入处理函数(命名叫 Process 吧)
  2. Process 计算这两个点的 X 轴和 Y 轴间距 dX =(X2 - X1)和 dY = (Y2 – Y 1)
    1. 如果 dX、dY 都等于 0,那么说明起点和重点已经连上了,结束处理
    2. 否则,得到中点(nX,nY)=(X1 + dX,Y1 + dY)
  3. 把中点(nX,nY)点亮
  4. 将起点、中点作为新的参数调用 Process
  5. 将中点、终点作为新的参数调用 Process
  6. 搞定。

算法是有了,但是,要到数字示波器上面直接调试,还挺麻烦的,因为要对记录 ADC 采样值的数组、LCD 屏幕显存数组、LCD 驱动程序等等软硬件相关的部分同时修改,并且还要硬件上调试才能看到结果。昨天硬件又不在手边,也没法调试。所以,就想到了 Excel。Excel 那些格子(Cell)模拟 LCD 界面那是极方便的,以前干过很多次了。

  1. 首先,在 Excel 上面框出来一片格子(Cells)当作显示器屏幕(B2~V18,对应列 2~22,行 2~18)
  2. 然后,放入 2 个按钮。1 个用来绘制连线,1 个用来清除屏幕
  3. 接着,定义起点(绿色,5287963 :)和终点(红色)的颜色。用颜色标识会比较醒目一点儿
  4. 最后,把上面的算法写进按钮的 VBA 代码中即可
   1: Sub cmdConnectPoints()

   2:     For c = 2 To 22

   3:         For r = 2 To 18

   4:             If Cells(r, c).Interior.Color = 5287936 Then

   5:                 x1 = c

   6:                 y1 = r

   7:             End If

   8:             If Cells(r, c).Interior.Color = RGB(255, 0, 0) Then

   9:                 x2 = c

  10:                 y2 = r

  11:             End If

  12:         Next

  13:     Next

  14:     Process x1, y1, x2, y2

  15: End Sub

  16:  

  17: Sub Process(x1, y1, x2, y2)

  18:     dx = Fix((x2 - x1) / 2)

  19:     dy = Fix((y2 - y1) / 2)

  20:     If dx = 0 And dy = 0 Then

  21:     

  22:     Else

  23:         nx = x1 + dx

  24:         If dx <= (x2 - nx) Then

  25:             ny = y1 + dy

  26:         Else

  27:             ny = y2 - dy

  28:         End If

  29:         Cells(ny, nx).Interior.Color = RGB(0, 0, 0)

  30:         Call Process(x1, y1, nx, ny)

  31:         Call Process(nx, ny, x2, y2)

  32:     End If

  33: End Sub

  34:  

  35: Sub cmdClear()

  36:     For c = 2 To 22

  37:         For r = 2 To 18

  38:             Cells(r, c).Interior.Color = RGB(255, 255, 255)

  39:         Next

  40:     Next

  41: End Sub

上面的代码中,有一段按照中点的 X 坐标距离起点和终点的远近来改变中点 Y 坐标计算方法的代码。如果中点 X 距离起点更近,那么 nY = Y1 + dY;否则,nY = Y2 - dY。这样的微调是为了让两点间的连线看上去更加均直、美观。如果去掉,那么,绘制的连线会“扭”向起点那一边,不美观。

效果就是这样的:

还有使用起来非常爽的操作视频:

这次做的数字示波器比上一个版本复杂点儿,采样率更高、控制也会更精细。所以,制作过程中借用了上一个版本的成果(用工具来制作工具,与软件开发也是相通的道理):

用 Excel 测试“绘制两点间连线”的算法的更多相关文章

  1. 转:Math: Math.atan() 与 Math.atan2() 计算两点间连线的夹角

    我们可以使用正切操作将角度转变为斜率,那么怎样利用斜率来转换为角度呢?可以利用斜率的反正切函数将他转换为相应的角度.as中有两个函数可以计算反正切,我们来看一下. 1.Math.atan() Math ...

  2. 任意两点间的最短路问题(Floyd-Warshall算法)

    /* 任意两点间的最短路问题(Floyd-Warshall算法) */ import java.util.Scanner; public class Main { //图的顶点数,总边数 static ...

  3. 利用百度API(JavaScript 版)实现在地图上绘制任一多边形,并判断给定经纬度是否在多边形范围内。以及两点间的测距功能

    权声明:本文为博主原创文章,未经博主允许不得转载. 利用百度API(JavaScript 版)实现在地图上绘制任一多边形,并判断给定经纬度是否在多边形范围内.以及两点间的测距功能. 绘制多边形(蓝色) ...

  4. 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器

    1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...

  5. 使用PostGIS完成两点间的河流轨迹及流经长度的计算

    基础准备工作 1.PostGIS 的安装 在安装PostGIS前首先必须安装PostgreSQL,然后再安装好的Stack Builder中选择安装PostGIS组件.具体安装步骤可参照 PostGI ...

  6. iOS: 如何正确的绘制1像素的线

    iOS 绘制1像素的线 一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮 ...

  7. 图算法之Floyd-Warshall 算法-- 任意两点间最小距离

    1.Floyd-Warshall 算法 给定一张图,在o(n3)时间内求出任意两点间的最小距离,并可以在求解过程中保存路径 2.Floyd-Warshall 算法概念 这是一个动态规划的算法. 将顶点 ...

  8. c++ 算法 栅格中两点之间连线

    屏幕划线,通过平面坐标系实现,基本组成是一个一个的点,起点为A,终点为B 本文的算法,可以实现平面栅格中,指定的A,B两点之间进行连线(代码中仅打印了两点间需要画出的坐标点) #include < ...

  9. iOS 绘制1像素的线

    一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到P ...

随机推荐

  1. Linux学习

    Linux 命令英文全称su:Swith user 切换用户,切换到root用户cat: Concatenate 串联uname: Unix name 系统名称df: Disk free 空余硬盘du ...

  2. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

  3. APP漏洞扫描用地址空间随机化

    APP漏洞扫描用地址空间随机化 前言 我们在前文<APP漏洞扫描器之本地拒绝服务检测详解>了解到阿里聚安全漏洞扫描器有一项静态分析加动态模糊测试的方法来检测的功能,并详细的介绍了它在针对本 ...

  4. Android-横竖屏切换问题(转)

    先附上链接:http://www.cnblogs.com/xiaoQLu/p/3324503.html 项目要求要做横竖屏,发现横屏的时候,生命周期函数会乱执行,网上找了一大堆资料. 结果如下: 只需 ...

  5. LBaaS 实现机制 - 每天5分钟玩转 OpenStack(125)

    上一节我们已经配置并测试 LBaaS,今天重点分析 Neutron 是如何用 Haproxy 来实现负责均衡的. 在控制节点上运行 ip netns,我们发现 Neutron 创建了新的 namesp ...

  6. 计算机程序的思维逻辑 (38) - 剖析ArrayList

    从本节开始,我们探讨Java中的容器类,所谓容器,顾名思义就是容纳其他数据的,计算机课程中有一门课叫数据结构,可以粗略对应于Java中的容器类,我们不会介绍所有数据结构的内容,但会介绍Java中的主要 ...

  7. 浅谈系列之 javascript原型与对象

    在我学习与使用javascript三个月中,我一直对javascript的继承关系以及prototype理解不清,导致很多时候为什么这么用说不出个所以然来.截止到本周为止,通过之前的学习以及自己的再学 ...

  8. SQL语句优化

    (1)      选择最有效率的表名顺序 ( 只在基于规则的优化器中有效 ) : ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名, FROM 子句中写在最后的表 ( 基础表dri ...

  9. SpringMVC一路总结(二)

    冰冻三尺非一日之寒.对技术的学习尤其得遵循这么一个理.在<SpringMVC一路总结(一)>中,清楚的总结了SpringMVC的入门案例,对于这类入门demo,理清套路,整理思绪是最为重要 ...

  10. “NOSQL” 杂谈

    引言: nosql 的兴起和革命,在我看来已经开始逐渐影响到了传统的sql的地位,但是仅仅是影响而已,取代是不太可能的. 正文: 两年前,一个偶然的机会开始接触到 nosql ( mongodb ). ...