图形学 直线算法

原创 2018年04月15日 12:12:17

1.DDA算法

我们在画直线时我们取的像素都在确定的两个像素里选择。


DDA直线算法在于利用K或者K的倒数,我们都知道k=dy/dx,所以是单位x内y的变化。


    不过在屏幕内我们通常以像素为单位,所以当|k|<1时我们以dx=1,dy=k。当|k|>=1,我们发现y比x走的多,|dy/dx|>1即dy>dx,所以为了在机器中我们以y走一个像素,x增加1/k。

    优点:比较易于实现,贴近数学

    缺点:有浮点数的处理(k的取整,浮点数的加法),效率不高


代码如下:

// DDA直线算法
function DDALine(x0,y0,x1,y1,color) {

  // 定义初始化参数
  var dx,dy,k,y;
  y=y0;
  x=x0;
  dx=0.0+x1-x0;
  dy=0.0+y1-y0;
  k=dy/dx;
  kReciprocal=dx/dy;

  // 根据点的位置关系(判断大小)、以及斜率将初始点设置好
  if (Math.abs(k)<1) {
    var xMax=x0>x1?x0:x1;
    var xMin=x0<x1?x0:x1;
    var yMax=xMin!=x0?y0:y1;
    var yMin=xMin==x0?y0:y1;

    // 根据增量k来画点
    for (var xn=xMin; xn<=xMax;) {
      drawPixel(xn,Math.floor(yMin+0.5),aposLocation,context);
      xn++;
      yMin+=k;
    }
  }else {
    var yMax=y0>y1?y0:y1;
    var yMin=y0<y1?y0:y1;
    var xMax=yMin!=y0?x0:x1;
    var xMin=yMin==y0?x0:x1;
    for (var yn=yMin; yn<=yMax;) {
      drawPixel(Math.floor(xMin+0.5),yn,aposLocation,context);
      yn++;
      xMin+=kReciprocal;
    }
  }
}

2.中点画线算法

中点画线就是以中点到直线的距离判断取点的位置,若中点带入直线,判断符号就能决策取哪个点。但是我们的k取不同值时,我们的判别式以及判别式增量需要变化。

    优点:进一步减少了浮点数的运算




代码如下:

// 中点直线画线
function MidPointLine(x0,y0,x1,y1,color) {


  var dx,dy,k,y,x;
  var a,b,d1,d2,d;
  dx=0.0+x1-x0;
  dy=0.0+y1-y0;
  k=dy/dx;
  kReciprocal=dx/dy;
  y=y0;x=x0;


  // 根据k的值来设置起始点
  if (Math.abs(k)<1) {
    var xMax=x0>x1?x0:x1;
    var xMin=x0<x1?x0:x1;
    var yMax=xMin!=x0?y0:y1;
    var yMin=xMin==x0?y0:y1;
  }else {
    var yMax=y0>y1?y0:y1;
    var yMin=y0<y1?y0:y1;
    var xMax=yMin!=y0?x0:x1;
    var xMin=yMin==y0?x0:x1;
  }


  x0=xMin;x1=xMax;y0=yMin;y1=yMax;y=y0;x=x0;


  if (Math.abs(k)<1) {
    a=y0-y1;
    b=x1-x0;
    b=k>0?b:-b;
    d=2*a+b;
    d1=k>0?2*a:2*(a+b);
    d2=k>0?2*(a+b):2*a;


    // 根据k的正负确定每次增加或减少
    var uFactor=k>0?1:0;
    var dFactor=k>0?0:-1;
    drawPixel(x,y,aposLocation,context);
    while (x<x1) {
      if (d<0) {
        x++;y+=uFactor;d+=d2;
      }else {
        x++;y+=dFactor;d+=d1;
      }
      drawPixel(x,y,aposLocation,context);
    }
  }else {
    a=x0-x1;
    b=y1-y0;
    b=k>0?b:-b;
    d=2*a+b;
    d1=k>0?2*a:2*(a+b);
    d2=k>0?2*(a+b):2*a;
    var dFactor=k>0?0:-1;
    var uFactor=k>0?1:0;
    drawPixel(x,y,aposLocation,context);
    while (y<y1) {
      if (d<0) {
        x+=uFactor;y++;d+=d2;
      }else {
        y++;x+=dFactor;d+=d1;
      }
      drawPixel(x,y,aposLocation,context);
    }
  }
}

3.Bresenham画线算法

这里是提前引入一个初值,然后后边不断累加一个增量来判断符号来判断点的位置。虽然引入0.5但是我们乘二就可以解决浮点数的问题,这个其实是DDA的变种,原理相似但是更为高级的是引入初始的判别值,经过变形去掉了浮点数,也只有一个增量。更易于机器的实现。

function BresenhamLine(x0,y0,x1,y1,color) {
  var x,y,dx,dy,c,dy_2,dx_2,e,k,kReciprocal;

  k=(y1-y0)/(x1-x0);

  if (Math.abs(k)<1) {
    var xMax=x0>x1?x0:x1;
    var xMin=x0<x1?x0:x1;
    var yMax=xMin!=x0?y0:y1;
    var yMin=xMin==x0?y0:y1;
  }else {
    var yMax=y0>y1?y0:y1;
    var yMin=y0<y1?y0:y1;
    var xMax=yMin!=y0?x0:x1;
    var xMin=yMin==y0?x0:x1;
  }

  x0=xMin;x1=xMax;y0=yMin;y1=yMax;y=y0;x=x0;

  dx=x1-x0;dy=y1-y0;e=-dx;
  x=x0;y=y0;
  dy_2=2*dy;
  dx_2=2*dx;


  if (Math.abs(k)<1) {
    if (k>0) {
      for (var i = 0; i <=dx; i++) {
        drawPixel(x,y,aposLocation,context);
        x++;e=e+dy_2;
        if (e>=0) {
          y++;e=e-dx_2;
        }
      }
    }else{
      e=-e;
      for (var i = 0; i <=dx; i++) {
        drawPixel(x,y,aposLocation,context);
        x++;e=e+dy_2;
        if (e<=0) {
          y--;e=e+dx_2;
        }
      }
    }
  }else{
      if (k>0) {
        for (var i = 0; i <=dy; i++) {
          drawPixel(x,y,aposLocation,context);
          y++;e=e+dx_2;
          if (e>=0) {
            x++;e=e-dy_2;
          }
        }
      }else {
        e=-e;
        for (var i = 0; i <=dy; i++) {
          drawPixel(x,y,aposLocation,context);
          y++;e=e+dx_2;
          if (e<=0) {
            x--;e=e+dy_2;
          }
        }
    }

  }

}

数据结构和算法

本次课主要是介绍在游戏开发中经常使用的数据结构,例如数组,链表,栈,队列,二叉树,递归等重要知识点讲解以及将它们里灵活的运用到算法里面。
  • 2015年01月29日 08:45

计算机图形学笔记-三种画线算法

1.DDA:在一个坐标轴上以单位间隔对线段取样,从而确定另一个坐标轴上最靠近路线的整数点。 如果斜率m1,则以单位Y间隔取样,逐步计算X值 x(k+1)=x(k)+1/m这个算法可以概括为以下过程:...
  • Hnubama
  • Hnubama
  • 2016-03-18 22:05:30
  • 2961

计算机图形学之--直线生成算法(一)

引言: 计算机图形学中首先
  • zhaogang1993
  • zhaogang1993
  • 2014-11-24 21:16:31
  • 1820

计算机图形学:3种画直线算法(转)

   计算机图形学:3种画直线算法分类:C/C++//---------------------------------------------------------------------//绘制...
  • tihu1111
  • tihu1111
  • 2010-10-15 09:36:00
  • 1861

[图形学]光栅直线算法

DDA算法(数值微分法)          浮点加法,依赖于斜截式          具体方法:每次x增加一个单位,y根据斜截式计算出相应的值,并且四舍五入取整(先加0.5,再下取整)  ...
  • ZJU_fish1996
  • ZJU_fish1996
  • 2016-01-26 16:36:17
  • 994

在java中实现图形学中的直线算法

有同学向我要在java中实现图形学中的椭圆算法,画直线的算法的程序,在此就献丑了,把上大学时用java写的源代码给先学者做个参考,下面是实现直线的算法//author computer np/*tes...
  • niuping1982
  • niuping1982
  • 2005-11-03 20:51:00
  • 1283

图形学各种算法代码

目的:实现画直线算法,画圆,画椭圆算法,二维直线裁剪算法 1. DDA算法,算法思想参考百度百科: http://baike.baidu.com/link?url=bKEk1Bmu6YO7gdPu...
  • damotiansheng
  • damotiansheng
  • 2015-01-31 21:31:14
  • 3937

【计算机图形学】基本图形元素:直线的生成算法

08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活。此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/de...
  • xiaowei_cqu
  • xiaowei_cqu
  • 2012-08-23 14:02:02
  • 13970

计算机图形学-基于OpenGL的直线段的裁剪算法

计算机图形学-直线段的裁剪算法在Opengl应用框架下实现C-S裁剪算法或L-B裁剪算法。完成一个四边形对两条线段的裁剪:四边形的左上角和右下角顶点分别为(100,100),(300,200),线段1...
  • u010968957
  • u010968957
  • 2017-05-28 09:57:40
  • 1721

java实现计算机图形学直线和圆的绘制算法

  • 2015年09月19日 12:34
  • 8KB
  • 下载
收藏助手
不良信息举报
您举报文章:图形学 直线算法
举报原因:
原因补充:

(最多只允许输入30个字)