前言
之前在CSDN问答看到一个同学询问数字积分法圆插补的Matlab轨迹实现程序。当时想解决这个问题,随之开始研究基于数字积分法的圆弧插补。
然而,经过搜索发现,尽管网上有大量的对数字积分法进行圆弧插补的文章。但这些文章普遍都是对基础理论的复述,并且几乎都是对圆心为(0,0)的第一象限圆弧进行插补。
但实际上,我们实际的圆弧插补操作并不是都在第一象限的一小段圆弧,更不是呆板的以(0,0)坐标原点作为圆弧的圆心。就此,来到了我们的问题——如何通过数字积分法实现任意圆弧插补。
数字积分法圆弧插补
数字积分法进行圆弧插补本身的解释定义网上到处都是,再此就不再赘述了。下面主要写一下实现跨象限圆弧插补的思路和部分程序。
如果你已经看过网上随处都能搜到的数字积分法进行圆弧插补的文章或者课件。你应该会初步意识到,数字积分法对圆弧进行插补在不同的象限以及不同的旋转方向是有着不一样的算法的——尽管核心思想是一致的。
那么,我们要通过数字积分法来实现任意圆弧的插补,就首先要实现四个象限内顺逆时针的圆弧插补。在实现了这八种不同情况(四个象限,每个象限顺逆时针两种情况)的圆弧插补之后,我们便可以先通过程序对起点和终点进行评估,判断两者是否在一个象限内。如果两者是在一个象限内,则根据其所在的象限和给定的旋转方向直接调用特定象限的插补算法。如果两者不在一个象限内,则我们先判断按照给定的旋转方向起点和终点间的圆弧都要经过哪几个象限,并获得相应的象限点。由此,将由起点→终点的问题,转化为起点→象限点→终点的问题。然后再将这些分段带入不同象限的算法来各自实现。
单个象限的圆弧插补程序
下面的示例程序,便是第一象限圆弧逆时针插补的程序。其中,x1、y1分别对应起点的x、y坐标;x2、y2分别对应终点的x、y坐标;n则是积分累加器的位数;jvx是x方向的函数寄存器(存储每个周期累加器的增加值),其初始值被赋值为起点的y坐标;jvy是y方向的函数寄存器,其初始值被赋值为起点的x坐标;jrx为x累加器,当它溢出时x将运行一个单位;jry为y累加器,当它溢出时y将运行一个单位。可以注意到,jrx和jry的初值都被赋为2^(n-1),即积分累加器所存储最大值的一半。这种方式叫做半加载,可以在计算开始时更快的输出位移。
由于是第一象限的逆时针插补,所以程序的结束条件为设置为插补的运行位置x坐标小于x2或y坐标大于y2。由于跳出循环的break在记录x、y操作之前,所以x坐标小于x2或y坐标大于y2时的x、y值并不会被存储于pos(pos用于记录插补过程的每一个移动位置)。
jvx=y1;
jvy=x1;
jrx=2^(n-1);
jry=2^(n-1);
x=x1;
y=y1;
while 1
flag=0;
jrx=jrx+jvx;
jry=jry+jvy;
if jrx>=n
jrx=jrx-n;
x=x-1;
jvy=jvy-1;
flag=1;
end
if jry>=n
jry=jry-n;
y=y+1;
jvx=jvx+1;
flag=1;
end
if x<x2 || y>y2
break;
end
if flag==1
pos(count,1)=x;
pos(count,2)=y;
count=count+1;
end
end
跨象限的圆弧插补
对于跨象限的圆弧插补,我们先通过一个循环来确定插补经过的象限,并把途径的象限点加入到起点和终点之间。然后将起点、途径的象限点、终点依次进行单个象限的插补生成,并最终将这些插补点合并为完全的插补路径。
以下图为例,起点在第一象限,终点在第三象限,圆弧方向为逆时针。则我们先判断出圆弧中途会途径第二象限,然后我们将中途途径的两个象限点计算出来。由此,我们把由起点到终点的问题,分解为——从起点到象限点1、从象限点1到象限点2、从象限点2到终点。这时,我们将这三组新的起点和终点带入到对应象限的插补程序,便得到了圆弧在一、二、三象限内对应的插补路径。我们再将这些路径进行合成,便得到了从起点到终点的完整插补路径。
实现效果
亦可通过matlab app designer实现相应的DDA插补app