1.DDA算法

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

DDA算法思想:增量思想

公式推导:

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

代码:

  1. void lineDDA(int x0, int y0, int x1, int y1, int color){
  2. int x;
  3. float dy, dx, y, m;
  4. dx = x1 - x0;
  5. dy = y1 - y0;
  6. m = dy / dx;
  7. y = y0;
  8. for (x = x0; x <= x1; x++){
  9. putpixel(x, (int)(y + 0.5), color);
  10. y += m;
  11. }
  12. }

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算法。

最终公式:

代码:

  1. void lineMidPoint(int x0, int y0, int x1, int y1, int color){
  2. int x = x0, y = y0;
  3. int a = y0 - y1, b = x1 - x0;
  4. int cx = (b >= 0 ? 1 : (b = -b, -1));
  5. int cy = (a <= 0 ? 1 : (a = -a, -1));
  6.  
  7. putpixel(x, y, color);
  8.  
  9. int d, d1, d2;
  10. if (-a <= b) // 斜率绝对值 <= 1
  11. {
  12. d = 2 * a + b;
  13. d1 = 2 * a;
  14. d2 = 2 * (a + b);
  15. while (x != x1)
  16. {
  17. if (d < 0)
  18. y += cy, d += d2;
  19. else
  20. d += d1;
  21. x += cx;
  22. putpixel(x, y, color);
  23. }
  24. }
  25. else // 斜率绝对值 > 1
  26. {
  27. d = 2 * b + a;
  28. d1 = 2 * b;
  29. d2 = 2 * (a + b);
  30. while (y != y1)
  31. {
  32. if (d < 0)
  33. d += d1;
  34. else
  35. x += cx, d += d2;
  36. y += cy;
  37. putpixel(x, y, color);
  38. }
  39. }
  40. }

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。否则结束。

代码:

  1. void lineBresenham1(int x0, int y0, int x1, int y1, long color)
  2. {
  3. int dx = abs(x1 - x0);
  4. int dy = abs(y1 - y0);
  5. int x = x0;
  6. int y = y0;
  7. int stepX = 1;
  8. int stepY = 1;
  9. if (x0 > x1) //从右向左画
  10. stepX = -1;
  11. if (y0 > y1)
  12. stepY = -1;
  13.  
  14. if (dx > dy) //沿着最长的那个轴前进
  15. {
  16. int e = dy * 2 - dx;
  17. for (int i = 0; i <= dx; i++)
  18. {
  19. putpixel(x, y, color);
  20. x += stepX;
  21. e += dy;
  22. if (e >= 0)
  23. {
  24. y += stepY;
  25. e -= dx;
  26. }
  27. }
  28. }
  29. else
  30. {
  31. int e = 2 * dx - dy;
  32. for (int i = 0; i <= dy; i++)
  33. {
  34. putpixel(x, y, color);
  35. y += stepY;
  36. e += dx;
  37. if (e >= 0)
  38. {
  39. x += stepX;
  40. e -= dy;
  41. }
  42. }
  43. }
  44. }

计算机图形学之扫描转换直线-DDA,Bresenham,中点画线算法的更多相关文章

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

    我的理解:在光栅图形学中,由于每一个点的表示都只能是整数值,所以光栅图形学实际只是对对实际图形的近似表示. 数值微分法(DDA):以下PPT截图来自北京化工大学李辉老师 代码实现: import ma ...

  2. 计算机图形学(二)输出图元_3_画线算法_2_DDA算法

    DDA算法        数字微分分析仪(digital differential analyzer, DDA)方法是一种线段扫描转换算法.基于使用等式(3.4)或等式(3.5)计算的&x或& ...

  3. 计算机图形学DDA画线法+中点画线法+Bresenham画线法

    #include <cstdio> #include <cstring> #include <conio.h> #include <graphics.h> ...

  4. 计算机图形学(二)输出图元_6_OpenGL曲线函数_2_中点画圆算法

    中点画圆算法        如同光栅画线算法,我们在每一个步中以单位间隔取样并确定离指定圆近期的像素位置.对于给定半径r和屏幕中心(xc,yc),能够先使用算法计算圆心在坐标原点(0, 0)的圆的像素 ...

  5. [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)

    上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...

  6. Bresenham画线算法

    [Bresenham画线算法] Bresenham是一种光栅化算法.不仅可以用于画线,也可以用用画圆及其它曲线. 通过lower与upper的差,可以知道哪一个点更接近线段: 参考:<计算机图形 ...

  7. 图形学入门(1)——直线生成算法(DDA和Bresenham)

    开一个新坑,记录从零开始学习图形学的过程,现在还是个正在学习的萌新,写的不好请见谅. 首先从最基础的直线生成算法开始,当我们要在屏幕上画一条直线时,由于屏幕由一个个像素组成,所以实际上计算机显示的直线 ...

  8. 计算机图形学(第2版 于万波 于硕 编著)第45页的Bresenham算法有错误

    计算机图形学(第2版 于万波 于硕 编著)第45页的Bresenham算法有错误: 书上本来要写的是以x为阶越步长的方法,但是他写的是用一部分y为阶越步长的方法(其实也写的不对),最后以x为阶越步长的 ...

  9. 计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具

    计算机图形学 opengl版本 第三版------胡事民 第四章  图形学中的向量工具 一   基础 1:向量分析和变换   两个工具  可以设计出各种几何对象 点和向量基于坐标系定义 拇指指向z轴正 ...

随机推荐

  1. bzoj-2251 外星联络

    题意: 给出一个字符串,求出现次数超过1的子串的出现个数. 字符串长度<=3000: 题解: 题目问的是子串的个数.那么首先我们要找到全部的子串. 而字符串的全部后缀的前缀能够不重不漏的表示全部 ...

  2. 前端基础——CSS盒子模型

    如今很多网页都是由很多个"盒子"拼接.嵌套而成,所以多少接触过网页设计的朋友一定都对CSS盒子模型有所了解. 为了更好的说明,先举个通俗的样例:在一个仓库中放了10个纸箱,每一个纸 ...

  3. EasyRTMP手机直播推送rtmp流flash无法正常播放问题

    本文转自EasyDarwin团队Kim的博客:http://blog.csdn.net/jinlong0603/article/details/52960750 问题简介 EasyRTMP是EasyD ...

  4. 九度OJ 1116:加减乘除 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1466 解决:902 题目描述: 根据输入的运算符对输入的整数进行简单的整数运算. 运算符只会是加+.减-.乘*.除/.求余%.阶乘!六个运 ...

  5. 使用注解来构造IoC容器-转

    新手,对于一些觉得有用的东西,直接转过来用了,自己理解的比较肤浅 使用注解来构造IoC容器 用注解来向Spring容器注册Bean.需要在applicationContext.xml中注册<co ...

  6. select监听多个client -- linux函数

    使用select函数能够以非堵塞的方式和多个socket通信.程序仅仅是演示select函数的使用,功能很easy,即使某个连接关闭以后也不会改动当前连接数.连接数达到最大值后会终止程序. 1. 程序 ...

  7. IE6 PNG图片不透明的解决方案-tinypng

    https://tinypng.com/ 把图片上传上去,就能处理这个问题啦. 纠正一下 再也不用把png图片一个个拖到TinyPNG进行在线压缩(和熊猫哥哥说再见了):再不用把JPG/JPEG图片拖 ...

  8. SAP 系统账期开关

    (1)OB52 财务账期-C 财务维护表 T001B[维护表T001B] (2)OB29 -C FI 财政年变式 (3)MMPV / MMRV -物料账期 MMPV 商品会计期间设置-结帐期间 [ 如 ...

  9. Non-parseable POM C:\Users\admin\.m2\repository\org\springframework问题解决方案

    现象: [INFO] Scanning for projects... [ERROR] [ERROR] Some problems were encountered while processing ...

  10. oracle rac常用的网络检查命令

    oracle的集群管理软件和数据库对私网依赖性很大,很多集群问题最后都可以归结到网络层面. 当集群出现问题时检查网络信息是必要的. 1.查看MTU的大小,确认所有节点的公网和私网网卡的MTU大小相同 ...