zoukankan      html  css  js  c++  java
  • DDA与Bresenham画线算法

    一、数字微分分析仪(digital differential analyzer, DDA)方法是一种线段扫描转换算法。在一个坐标轴上以单位间隔对线段取样,从而确定另一个坐标轴上最靠近线路径的对应整数值。主要是根据直线公式y = kx + b来推导出来的,其关键之处在于如何设定单位步进,即一个方向的步进为单位步进,另一个方向的步进必然是小于1。

    算法过程:

    输入线段两个端点的像素位置,端点位置间的水平和垂直差赋给参数dx和dy。绝对值大的参数确定steps的值。从像素位置(xBegin,yBegin)开始,确定沿线段生成下一个像素位置的每一步所需的偏移量,并循环上述过程setps次。假如dx的绝对值大于dy的绝对值,且xBegin小于xEnd,那么x和y方向的增量值分别为1和m。假如x方向的变化较大,但xBegin大于xEnd,那么就采用减量-1和-m来生成线段上的每个点。在其他情况下,y方向使用单位增量(或减量),x方向使用1/m的增量(或减量)。

     1 inline int Round(const float a) { return static_cast<int>(a + 0.5); }
     2 
     3 void LineDDA(int xBegin, int yBegin, int xEnd, int yEnd)
     4 {
     5     int dx = xEnd - xBegin;
     6     int dy = yEnd - yBegin;
     7     int steps, k;
     8 
     9     float xIncrement, yIncrement;
    10     float x = static_cast<int>(xBegin);
    11     float y = static_cast<int>(yBegin);
    12 
    13     if (fabs(dx) > fabs(dy)) {
    14         steps = fabs(dx);
    15     }
    16     else {
    17         steps = fabs(dy);
    18     }
    19 
    20     xIncrement = static_cast<float>(dx) / static_cast<float>(steps);
    21     yIncrement = static_cast<float>(dy) / static_cast<float>(steps);
    22 
    23     glBegin(GL_POINTS);
    24 
    25     for (k = 0; k < steps; ++k) {
    26         x += xIncrement;
    27         y += yIncrement;
    28         glVertex2i(round(x), round(y));
    29     }
    30     glEnd();
    31 }

    二、Bresenham画线算法是一种精确而有效的光栅线生成算法,该算法仅仅使用了增量整数计算。

     

      

    在取样位置,用来标识两个像素与数学上线路径的垂直偏移。在像素列位置处的直线上的坐标可计算为

       

    那么

       

         

    要确定两像素中哪一个更接近线路径,需测试两个像素偏移的差:

       

       

    相减可得到

       

           

    算法过程:

    时的Bresenham画线算法:

    1.输入线段的两个端点,并将左端点存储在(xBegin, yBegin)中;

    2.将(xBegin, yBegin)装入帧缓存,画出第一个点;

    3.计算常量,并得到决策参数的第一个值:

       

    4.从开始,在沿线路径的每个处,进行下列检测:

    如果,下一个要绘制的点是,并且

       

    否则,下一个要绘制的点是,并且

       

    5.重读步骤4,共;

     1 void LineBresenham(int xBegin, int yBegin, int xEnd, int yEnd)
     2 {
     3     int dx = fabs(xEnd - xBegin);
     4     int dy = fabs(yEnd - yBegin);
     5 
     6 
     7     int p = 2 * dy - dx;
     8     int two_dy = 2 * dy;
     9     int two_dy_minus_dx = 2 * (dy - dx);
    10     int x, y;
    11     int yName;
    12 
    13     if (xBegin > xEnd) {
    14         yName = yBegin - yEnd;
    15         x = xEnd;
    16         y = yEnd;
    17         xEnd = xBegin;
    18     }
    19     else {
    20         yName = yEnd - yBegin;
    21         x = xBegin;
    22         y = yBegin;
    23     }
    24     while (x <= xEnd) {
    25         glBegin(GL_POINTS);
    26         glVertex2i(x, y);
    27         glEnd();
    28         
    29         if (dx == 0 && y < yEnd) {
    30             y++;
    31             continue;
    32         }
    33         if (p < 0) {
    34             x++;
    35             p += two_dy;
    36         }
    37         else if (yName > 0) {
    38             y++;
    39             x++;
    40             p += two_dy_minus_dx;
    41         }
    42         else if (yName < 0) {
    43             y--;
    44             x++;
    45             p += two_dy_minus_dx;
    46         }
    47     }
    48 }
  • 相关阅读:
    [APIO2018] Duathlon 铁人两项
    「PKUWC2018」随机游走
    「2018山东一轮集训」 Tree
    「2018山东一轮集训」Game
    [Lydsy1805月赛] quailty 算法
    CodeForces
    CodeForces
    「2018山东一轮集训」鸽子
    python序列化
    python的shutil模块
  • 原文地址:https://www.cnblogs.com/clairvoyant/p/5523429.html
Copyright © 2011-2022 走看看