计算机图形学之扫描转换直线-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,Bresenham,中点画线算法的更多相关文章
- 扫描转换算法——DDA、中点画线画圆、椭圆
我的理解:在光栅图形学中,由于每一个点的表示都只能是整数值,所以光栅图形学实际只是对对实际图形的近似表示. 数值微分法(DDA):以下PPT截图来自北京化工大学李辉老师 代码实现: import ma ...
- 计算机图形学(二)输出图元_3_画线算法_2_DDA算法
DDA算法 数字微分分析仪(digital differential analyzer, DDA)方法是一种线段扫描转换算法.基于使用等式(3.4)或等式(3.5)计算的&x或& ...
- 计算机图形学DDA画线法+中点画线法+Bresenham画线法
#include <cstdio> #include <cstring> #include <conio.h> #include <graphics.h> ...
- 计算机图形学(二)输出图元_6_OpenGL曲线函数_2_中点画圆算法
中点画圆算法 如同光栅画线算法,我们在每一个步中以单位间隔取样并确定离指定圆近期的像素位置.对于给定半径r和屏幕中心(xc,yc),能够先使用算法计算圆心在坐标原点(0, 0)的圆的像素 ...
- [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)
上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...
- Bresenham画线算法
[Bresenham画线算法] Bresenham是一种光栅化算法.不仅可以用于画线,也可以用用画圆及其它曲线. 通过lower与upper的差,可以知道哪一个点更接近线段: 参考:<计算机图形 ...
- 图形学入门(1)——直线生成算法(DDA和Bresenham)
开一个新坑,记录从零开始学习图形学的过程,现在还是个正在学习的萌新,写的不好请见谅. 首先从最基础的直线生成算法开始,当我们要在屏幕上画一条直线时,由于屏幕由一个个像素组成,所以实际上计算机显示的直线 ...
- 计算机图形学(第2版 于万波 于硕 编著)第45页的Bresenham算法有错误
计算机图形学(第2版 于万波 于硕 编著)第45页的Bresenham算法有错误: 书上本来要写的是以x为阶越步长的方法,但是他写的是用一部分y为阶越步长的方法(其实也写的不对),最后以x为阶越步长的 ...
- 计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具
计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具 一 基础 1:向量分析和变换 两个工具 可以设计出各种几何对象 点和向量基于坐标系定义 拇指指向z轴正 ...
随机推荐
- Active Directory组织单位(Organizational Unit)操作汇总
前言 本章聊Active Directory的组织单位(OU)的新增.修改.移动等操作,使用.NET Framework 为我们提供的System.DirectoryServices程序集. 不积跬步 ...
- ActiveMQ 消息持久化到Mysql数据库
[root@txylucky local]# tar -zxvf apache-activemq-5.15.8-bin.tar.gz[root@txylucky local]# mv apache-a ...
- 版本控制器 git
摘要:版本控制器是码农必备的工具,很多常用的,像svn,git,cvs等,工作中用过svn,Tortoisehg,firefly,其实大同小异,现在简单介绍下git,以及它的一些常用命令. 在wind ...
- 九度OJ 1112:拦截导弹 (DP、最长下降子序列)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3124 解决:1525 题目描述: 某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能 ...
- 使用JavaScript获取浏览器UserAgent
可以在浏览器地址栏输入about:version来查看UserAgent等信息 但是在Win10系统,本人亲测,IE和Edge用这样的方式都获取不到信息 在我惯用的QQ浏览器上倒是可以获取到 为了能方 ...
- mysql 修改语法格式
1.修改字段注释格式 alter table {table} modify column {column} {type} comment '{comment}';
- java之EJB
EjB,只是一个服务端运行组件,公开接口供客户端以C/S方式调用而已. 最直白,最本质的解释,可参见: http://blog.csdn.net/jojo52013145/article/detail ...
- HDU5965 扫雷 —— dp递推
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5965 题解: 1. 用a[]数组记录第二行的数字,用dp[]记录没一列放的地雷数.如果第一列的地雷数d ...
- java HttpClient GET请求
HttpClient GET请求小实例,先简单记录下. package com.httpclientget; import java.io.IOException; import org.apache ...
- win8系统在安装软件时安装framework3.5失败的解决办法
win8系统在,许多软件都需求安装framework3.5,但是很多用户都是安装失败,联网失败,据网上的许多人说有用cmd输入命令,然后到100%,就会成功安装framework3.5(如这个方法:w ...