扩展DDA与普通DDA区别在哪里

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扩展DDA与普通DDA区别在哪里相关的知识,希望对你有一定的参考价值。

//很多人答错,我说的DDA是机床数控里的DDA(digital differential analyzer)插值方法

最近学机床数控技术与原理,有点疑惑。DDA插补我理解是通过计算溢出来确定进给量,扩展DDA我理解就是将一段轨迹分成一小段一小段的。那么在扩展DDA里,在每个插补周期内,机床具体要如何进给,轨迹是怎么样的,它和普通DDA插补有什么区别呢?

DDA算法的主要核心思想是在直线段的扫描转换算法的基础上,去掉效率比较低下的乘法操作。因此需要引入相关的增量思想计算机图形学中一种基于直线的微分方程来生成直线的方法,由于有浮点数运算与取整,该算法不利于硬件实现,扩展DDA是在DDA积分法的基础上发展起来的,但它的精度较高,运行速度快,可用于多坐标的控制中。 参考技术A 在于运动方面 参考技术B 又称数值微分法,是计算机图形学中一种基于直线的微分方程来生成直线的方法 参考技术C [url=http://www.cnblogs.com/l14133/p/5173460.html]http://www.cnblogs.com/l14133/p/5173460.html[/url]

fDDA是快速DDA认证,fDDA用于qPBOC,DDA用于PBOC,fDDA与DDA认证只有部分不同(关于区别本文有讲)
本文就使用公司交行工资卡跑一遍fDDA流程,
DDA(fDDA)的步骤可以这样理解:先执行 SDA大部分,再执行DDA(fDDA)特有的步骤

步骤1. 恢复IC卡公钥
在SDA 阶段取得的发卡行公钥,在DDA时还有一个用途,就是恢复IC卡公钥. 可以用下面的公式表示:

发卡行公钥+IC 卡公钥证书+RSA 算法=IC卡公钥
通过RSA算法,使用发卡行公钥解析IC卡公钥证书得出的IC卡公钥:
恢复数据头6A
证书格式
04
应用主账号
62226206200171XXXXXF(为了隐私最后几位用XX代替)
证书失效日期
1224
证书序列号
100001
哈希算法标识
01
IC卡公钥算法标识
01
IC卡公钥长度
80
IC卡公钥指数长度
01
IC卡公钥或IC卡公钥的最左边字节
F10B7CD3B0AA7002E70B1959E33210487A5251C39C8D3A88DD77FAAC129171E6DF61DD76809AA0F7459434D8771CA23217BCC5CDBF194E2995FAE5C031827FBDFEEC25E0BCA3AF04B9296A37820604B9A82F3AEB03BDE46F06FFED992FE35A615A2AFFF3C584696F45D3B231C34337532D9F956B528E2EBF2523E27838E9B67BBBBBBBBBBBBB
哈希结果
350F02EC13781B64B6D7DFC4ED85CD00D09E515B
恢复数据结尾
BC
HASH校验的方法:
将上表中第2个到第10个数据元(即从证书格式直到IC卡公钥或IC卡公钥的最左边字节)从左到右连接,再把IC卡公钥的余项(如果有)+IC卡公钥指数+需认证的静态数据(请参考SDA)+静态数据认证标签列表(如果存在),然后计算HASH结果与IC卡公钥中的HASH结果比对,由此可见动态数据验证同样使用静态数据部分
参考技术D fDDA是快速DDA认证,fDDA用于qPBOC,DDA用于PBOC,fDDA与DDA认证只有部分不同(关于区别本文有讲)
本文就使用公司交行工资卡跑一遍fDDA流程,
DDA(fDDA)的步骤可以这样理解:先执行 SDA大部分,再执行DDA(fDDA)特有的步骤

计算机图形学之扫描转换直线-DDA,Bresenham,中点画线算法

1.DDA算法

DDA(Digital Differential Analyer):数字微分法

DDA算法思想:增量思想

公式推导:

技术分享图片

效率:采用了浮点加法和浮点显示是需要取整

代码:

void lineDDA(int x0, int y0, int x1, int y1, int color){
    int x;
    float dy, dx, y, m;
    dx = x1 - x0;
    dy = y1 - y0;
    m = dy / dx;
    y = y0;
    for (x = x0; x <= x1; x++){
        putpixel(x, (int)(y + 0.5), color);
        y += m;
    }
}

2.中点画线法

采用了直线的一般式:Ax+By+C=0

技术分享图片

当k在(0,1]中时,每次在x方向上加1,y方向上加1或不变:

技术分享图片

当Q在M上方时,取Pu点;

当Q在M下方时,取Pd点。

接下来:

技术分享图片

然后中点画线的计算:

技术分享图片

di需要两个乘法和四个加法算,比DDA差的多,但是di可以用增量法求

当d<0时

技术分享图片

当d>=0时

技术分享图片

d的初始值d0:

技术分享图片

中点算法计算为:

技术分享图片

如果将d换成2d,就只有整数运算,优于DDA算法。

技术分享图片

最终公式:

技术分享图片

代码:

void lineMidPoint(int x0, int y0, int x1, int y1, int color){
    int x = x0, y = y0;
    int a = y0 - y1, b = x1 - x0;
    int cx = (b >= 0 ? 1 : (b = -b, -1));
    int cy = (a <= 0 ? 1 : (a = -a, -1));

    putpixel(x, y, color);

    int d, d1, d2;
    if (-a <= b)     // 斜率绝对值 <= 1  
    {
        d = 2 * a + b;
        d1 = 2 * a;
        d2 = 2 * (a + b);
        while (x != x1)
        {
            if (d < 0)
                y += cy, d += d2;
            else
                d += d1;
            x += cx;
            putpixel(x, y, color);
        }
    }
    else                // 斜率绝对值 > 1  
    {
        d = 2 * b + a;
        d1 = 2 * b;
        d2 = 2 * (a + b);
        while (y != y1)
        {
            if (d < 0)
                d += d1;
            else
                x += cx, d += d2;
            y += cy;
            putpixel(x, y, color);
        }
    }
}

3.Bresenham算法

DDA使画直线每步只有一个加法。

中点画线法使画直线每步只有一个整数加法。

Bresenham算法提供一个更一般的算法,使适用范围增大。

该算法的思想是通过各行、各列像素中心构造一组虚拟网格线,按照直线起点到终点的顺序,计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。

假设每次x+1,y的递增(减)量为0或1,它取决于实际直线与最近光栅网格点的距离,这个距离的最大误差为0.5。

技术分享图片

误差项d的初值d 0=0,d=d+k,一旦d≥1,就把它减去1,保证d的相对性,且在0、1之间。

然后有下面计算公式:

技术分享图片

怎么提升到整数算法?

答案是让e=d-0.5

e0=-0.5

每循环一次:e = e+k
if (e>0) then e = e-1

技术分享图片

e+k这还是一个浮点加法

因为k=△y/△x

因为用误差项的符号,可以用e*2*△x来替换 e:

e0=-△x

每循环一次:e = e+2△y
if (e>0) then e = e-2△x

这已经变成为整数加法

算法步骤:

算法步骤为:
1.输入直线的两端点P 0(x 0,y 0)和P 1(x 1,y 1)。
2.计算初始值△x、△y、 e=-△x、x=x 0、y=y 0。
3.绘制点(x,y)。
4.e更新为 e+2△y,判断e的符号。若e>0,则(x,y)更新为
(x+1,y+1),同时将e更新为 e-2△x;否则(x,y)更新为
(x+1,y)。
5.当直线没有画完时,重复步骤3和4。否则结束。

代码:

void lineBresenham1(int x0, int y0, int x1, int y1, long color)
{
    int dx = abs(x1 - x0);
    int dy = abs(y1 - y0);
    int x = x0;
    int y = y0;
    int stepX = 1;
    int stepY = 1;
    if (x0 > x1)  //从右向左画  
        stepX = -1;
    if (y0 > y1)
        stepY = -1;

    if (dx > dy)  //沿着最长的那个轴前进  
    {
        int e = dy * 2 - dx;
        for (int i = 0; i <= dx; i++)
        {
            putpixel(x, y, color);
            x += stepX;
            e += dy;
            if (e >= 0)
            {
                y += stepY;
                e -= dx;
            }
        }
    }
    else
    {
        int e = 2 * dx - dy;
        for (int i = 0; i <= dy; i++)
        {
            putpixel(x, y, color);
            y += stepY;
            e += dx;
            if (e >= 0)
            {
                x += stepX;
                e -= dy;
            }
        }
    }
}









以上是关于扩展DDA与普通DDA区别在哪里的主要内容,如果未能解决你的问题,请参考以下文章

DDA算法和Bresenham算法

什么是 DDA啊 ?谢谢了,大神帮忙啊

扫描转换算法——DDA中点画线画圆椭圆

计算机图形学之扫描转换直线-DDA,Bresenham,中点画线算法

OpenGL实现DDA画线算法

计算机图形学输出图元_3_画线算法_2_DDA算法