计算机图形学 实验 数值微分(DDA)法、中点画线法、Bresenham算法
VS中直线的绘制—计算机图形学实验报告一
Else
k += 2 * (dy - dx)
y = y + 1
Enห้องสมุดไป่ตู้If
x = x + 1
EndWhile
Else
k = 2 * dx - dy
Whiley < y2
g.DrawEllipse(p,CInt(x),CInt(y), 1, 1)
Ifk < 0Then
k += 2 * dx
08地信
学号
200875000203
姓名
指导老师
课程名称
计算机图形学
实验题目
直线的绘制
成绩
一、实验目的:
熟练掌握绘制直线的DDA算法、中点画线算法和Bresenham画线算法。
二、实验准备:
学习绘制直线的DDA算法、中点画线算法和Bresenham画线算法,注意考虑不同斜率条件下算法的变化。
三、实验内容:
MessageBox.Show("请输入正确的坐标!", "警告!", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
x1 =CDbl(TextBox1.Text)
y1 =CDbl(TextBox2.Text)
x2 =CDbl(TextBox3.Text)
Dimx1, y1, x2, y2, dx, dy, x, y, k, a, bAsDouble
DimgAsGraphics = PictureBox1.CreateGraphics
DimpAsPen =NewPen(Color.Green, 1)
直线算法的技巧
直线算法的技巧直线算法是计算机图形学中最基本的算法之一,用于在屏幕上绘制直线。
本文将就直线算法的一些技巧进行详细讲解。
直线算法通常需要一个起始点(x1, y1)和一个终止点(x2, y2),然后在这两个点之间绘制一条直线。
最基本的直线算法是数字微分分析法(DDA)和中点画线法(Bresenham算法)。
这两种算法的核心思想都是利用直线的斜率来进行像素点的逼近。
在使用DDA算法绘制直线时,可以通过增加步长来减少精度损失。
DDA算法的步骤如下:1. 计算斜率:计算直线的斜率m = (y2 - y1) / (x2 - x1)。
2. 判断斜率:判断斜率的绝对值是否在0和1之间。
如果是,我们可以选择在x上递增逼近y或在y上递增逼近x。
3. 增加步长:计算递增的步长,对于长度较大的直线,可以通过增加步长来减少计算数量。
4. 开始绘制:从起始点开始,根据斜率和步长计算下一个要绘制的像素点的坐标。
5. 终止条件:当当前的坐标达到终止点时,终止绘制。
中点画线法(Bresenham算法)是一种更高效的直线算法,它通过使用整数运算和位移来避免了浮点数运算,提高了绘制速度。
Bresenham算法的步骤如下:1. 初始化:初始化起始点(x1, y1)和终止点(x2, y2),并计算dx = x2 - x1 和dy = y2 - y1 。
2. 计算斜率:判断斜率m = dy / dx,以决定使用什么方式增加x和y的值(水平递增或垂直递增)。
3. 计算误差:计算误差项E = -0.5,并对dx和dy进行判断,确定每个点移动时误差项的变化。
若dx > dy,则E += dy;否则,E += dx。
4. 绘制像素点:从起始点开始,每次根据误差项判断,决定是在y上递增还是在x上递增,并根据计算出的新的坐标绘制像素点。
5. 更新误差项:在每次绘制完成后,根据dx和dy更新误差项的值。
6. 终止条件:当当前的坐标达到终止点时,终止绘制。
分别解释直线生成算法dda法,中点画线法和bresenham法的基本原理
分别解释直线生成算法dda法,中点画线法和
bresenham法的基本原理
直线生成算法DDA法、中点画线法和Bresenham法的基本原理如下:
1. DDA直线生成算法:基于差分运算的直线生成算法。
通过将直线分割成
若干个相邻的像素点,并按照一定的步长进行逐点绘制,实现直线的绘制。
算法主要涉及到线性插值的思想,即根据已知的两点坐标,通过计算它们之间的差值,然后根据这个差值和步长来确定新的像素点的位置。
2. 中点画线法:一种线段绘制算法,从线段的起点和终点出发,按照一定的规则向终点逐步逼近,并在途中以控制变量的方式得出每个像素点的坐标,从而绘制出所需的线条。
具体实现中,通过计算线段斜率的变化情况,分为斜率小于1和大于等于1两种情况,并采用Bresenham的对称性原理,以中点的颜色来控制每个像素点的生长方向,从而获得较高的绘制效率和图像质量表现。
3. Bresenham算法:通过一系列的迭代来确定一个像素点是否应该被绘制。
对于一条从点(x1,y1)到点(x2,y2)的直线,首先计算出斜率k。
然后,通过比较每个像素点的y值到直线上的y值,来决定哪些像素点应该被绘制。
当斜率k大于等于1时,在x方向上迭代,而对于每个x值,计算出y值,并将像素点(x,y)绘制。
当斜率k小于1时,在y方向上迭代,而对于每个y值,计算出x值,并将像素点(x,y)绘制。
以上内容仅供参考,如需更多信息,建议查阅相关文献或咨询数学专业人士。
计算机图形学划线实验报告
实验一直线、圆(弧)生成算法一、实验目的及要求1. 了解光栅图形显示器的工作原理和特点;2. 学习C/VC环境下的基本绘图方法;3. 实践与巩固直线的基本生成算法。
?4. 掌握直线扫描转换算法的原理及实现;5. 学习圆(弧)的基本生成算法;6. 实践圆(弧)的基本生成算法;7. 掌握圆弧扫描转换算法的原理及实现;二、理论基础1、有关直线生成算法有DDA(数值微分)、中点画线线算法、Bresenham生成算法数值微分法先算出直线的斜率,然后从起点开始,确定最佳逼近于直线的y坐标。
假设起点的坐标为整数。
让x递增1,y相应递增k。
中点划线算法中若直线在x方向增加一个单位,y的增量只能在0、1之间。
假设当前像素点已经确定,下一像素点就只可能有两种情况,将这两点的中点带入直线方程中,通过中点在直线的上、下方来判断下一点的坐标。
Bresenham算法是通过各行、各列像素中心构造一组虚拟网络格线,按直线从起点到中点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
2、有关画圆的算法圆的扫描转换(中点画圆法)、Bresenham画圆算法圆的扫描转换算法同中点画线类似,将圆分为8份,先讨论圆的第一象限上半部分,从(0,R)点顺时针确定最佳逼近于该圆弧的像素序列。
之后通过对称画出全部圆。
Bresenham画圆算法考虑圆在第一象限上的点,每确定一像素,则下一像素有三种可能,通过判断右下方的像素与圆的位置关系再分为三种情况,之后通过这三个点与圆的距离远近确定最佳逼近像素。
三、算法设计与分析1、数值微分法int x0=0,y0=0,x1=800,y1=400;2中点画线法COLORREF color=RGB(100,25,108);int x0=0,y0=0,x1=800,y1=400; 5的正负判断下一像素点的取值。
当e大于0即对应d>的情况,给e减去1以保证在d始终在0、1之间。
在画其他斜率时只需根据实际情况对该程序做一定的改动。
简述画直线的几种操作方式
简述画直线的几种操作方式一、概述画直线是计算机图形学中的基本操作之一,通常用于绘制线条、边框等。
在计算机图形学中,有多种方式可以实现画直线的功能。
本文将介绍几种常见的画直线操作方式。
二、DDA算法DDA算法是一种基本的画直线算法,它采用逐点比较的方式来确定像素点的位置。
具体实现过程如下:1. 计算出两个端点之间的斜率k;2. 根据斜率k确定每个像素点在x轴和y轴上移动的距离;3. 从起始点开始,不断计算下一个像素点的位置,并在屏幕上绘制。
优点:实现简单,适用于硬件实现。
缺点:精度不高,容易出现锯齿状。
三、Bresenham算法Bresenham算法是另一种常见的画直线算法,它采用整数运算来确定像素点位置。
具体实现过程如下:1. 计算出两个端点之间的斜率k;2. 根据斜率k确定每个像素点在x轴和y轴上移动的距离;3. 从起始点开始,根据当前位置和误差值选择下一个像素点,并在屏幕上绘制。
优点:精度高,画出的直线平滑。
缺点:实现复杂,不适用于硬件实现。
四、中点画线算法中点画线算法是一种基于Bresenham算法的改进版,它通过引入中点来减少计算量。
具体实现过程如下:1. 计算出两个端点之间的斜率k;2. 根据斜率k确定每个像素点在x轴和y轴上移动的距离;3. 从起始点开始,根据当前位置和误差值选择下一个像素点,并在屏幕上绘制;4. 在误差值发生变化时,更新中点的位置。
优点:精度高,计算量较小。
缺点:实现复杂,不适用于硬件实现。
五、直线段裁剪直线段裁剪是指将一条直线段截取为位于窗口内部的一段直线。
常见的裁剪算法有Cohen-Sutherland算法和Liang-Barsky算法。
Cohen-Sutherland算法将窗口分为九个区域,并通过比较端点与窗口边界的关系来确定哪些部分需要保留。
Liang-Barsky算法则通过计算交点来确定截取后的直线段。
六、总结以上介绍了几种常见的画直线操作方式,包括DDA算法、Bresenham算法、中点画线算法以及直线段裁剪算法。
《计算机图形学》实验指导书
计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现DDA、中点画线算法和Bresenham画线算法 (24)实验二实现Bezier曲线 (25)实验三实现B样条曲线 (26)实验四实现多边形填充的边界标志算法 (27)实验五实现裁剪多边形的Cohen-Sutherland算法 (28)实验六二维图形的基本几何变换 (30)实验七画图软件的编制 (31)实验一实现DDA、中点画线算法和Bresenham画线算法【实验目的】1、掌握直线的多种生成算法;2、掌握二维图形显示原理。
【实验环境】VC++6.0/ BC【实验性质及学时】验证性实验,2学时,必做实验【实验内容】利用任意的一个实验环境,编制源程序,分别实现直线的三种生成算法,即数字微分法(DDA)、中点画线法以及Bresenham画线算法。
【实验原理】1、数字微分法(Digital Differential Analyzer,DDA)算法思想:基于直线的微分方程来生成直线。
ε=1/max(|△x|,|△y|)max(|△x|,|△y|)=|△x|,即|k|≤1 的情况:max(|△x|,|△y|)=|△y|,此时|k|≥1:2、中点画线法算法思想:每次在最大位移方向上走一步,另一方向是否走步取决于误差项的判断。
3、Bresenham画线算法算法思想:其基本思想同中点算法一样,即每次在最大位移方向上走一步,而另一个方向是否走步取决于误差项的判断。
【实验要求】1.上交源程序;2.上交实验报告,实验报告内容如下:(1) 实验名称(2) 实验目的(3) 算法实现的设计方法及程序流程图(4) 程序结果分析【分析与思考】(1) 上述所阐述的三个算法,其基本算法只能适用于直线的斜率(|K|<=1) 的情形,如何将上述算法进行推广,使其能够处理任意斜率的直线?(2) 计算机显示屏幕的坐标圆心在哪里,与我们平时的习惯有什么差异,如何协调二者?实验二 实现Bezier 曲线【实验目的】1、掌握Bezier 曲线的定义;2、能编程实现N 次Bezier 曲线的绘制与显示。
计算机图形学
三个常用算法数值微分法(DDA)中点画线法Bresenham算法
区域连通:
区域指已经表示成点阵形式的填充图形,它是象素的集合。
区域可采用内点表示和边界表示两种表示形式。
区域可分为4向连通区域和8向连通区域。
区域填充指先将区域的一点赋予指定的颜色,然后将该颜色扩展到整个区域的过程。
区域填充算法要求区域是连通的
算法步骤:
首先填充种子点所在扫描线上的位于给定区域的一个区段
然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来。
反复这个过程,直到填充结束。
多边形扫描转换:多边形有两种重要的表示方法:顶点表示和点阵表示。
多边形的扫描转换:把多边形的顶点表示转换为点阵表示。
逐点判断法;
扫描线算法;
边界标志。
计算机图形学常用算法及代码大全
2。
1。
1 生成直线的DDA算法数值微分法即DDA法(Digital Differential Analyzer),是一种基于直线的微分方程来生成直线的方法.一、直线DDA算法描述:设(x1,y1)和(x2,y2)分别为所求直线的起点和终点坐标,由直线的微分方程得= m =直线的斜率(2-1)可通过计算由x方向的增量△x引起y的改变来生成直线:x i+1=x i+△x (2-2)y i+1=y i+△y=y i+△x·m (2-3) 也可通过计算由y方向的增量△y引起x的改变来生成直线:y i+1=y i+△y (2-4)x i+1=x i+△x=x i+△y/m (2-5) 式(2-2)至(2-5)是递推的.二、直线DDA算法思想:选定x2-x1和y2-y1中较大者作为步进方向(假设x2-x1较大),取该方向上的增量为一个象素单位(△x=1),然后利用式(2-1)计算另一个方向的增量(△y=△x·m=m)。
通过递推公式(2-2)至(2-5),把每次计算出的(x i+1,y i+1)经取整后送到显示器输出,则得到扫描转换后的直线。
之所以取x2-x1和y2-y1中较大者作为步进方向,是考虑沿着线段分布的象素应均匀,这在下图中可看出。
另外,算法实现中还应注意直线的生成方向,以决定Δx及Δy是取正值还是负值。
三、直线DDA算法实现:1、已知直线的两端点坐标:(x1,y1),(x2,y2)2、已知画线的颜色:color3、计算两个方向的变化量:dx=x2-x1dy=y2-y14、求出两个方向最大变化量的绝对值:steps=max(|dx|,|dy|)5、计算两个方向的增量(考虑了生成方向):xin=dx/stepsyin=dy/steps6、设置初始象素坐标:x=x1,y=y17、用循环实现直线的绘制:for(i=1;i〈=steps;i++){putpixel(x,y,color);/*在(x,y)处,以color色画点*/x=x+xin;y=y+yin;}五、直线DDA算法特点:该算法简单,实现容易,但由于在循环中涉及实型数的运算,因此生成直线的速度较慢。
计算机图形学直线DDA算法和Bresenham算法
Graphicsgraphics =this.CreateGraphics();
bmp =newBitmap(this.ClientRectangle.Width,this.ClientRectangle.Height);
DDAline(27, 19, 200, 183, bmp);
graphics.DrawImage(bmp,newRectangle(0, 0,this.ClientRectangle.Width,this.ClientRectangle.Height));
{
x++;
y = x + k;
}
else
{
y++;
x = y + (1 / k);
}
{
bmp.SetPixel(x, y,Color.Red);
}
}
}
privatevoidbutton1_Click(objectsender,EventArgse)
{
Graphicsgraphics =this.CreateGraphics();
④代码与运行结果;
usingSystem;
usingSystem.Collections.Generic;
ponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
③实验步骤:
1、在C#环境下,设计界面,添加4个文本框,三个命令按钮;
2、在代码编写窗口,编写DDA、中点直线生成算法、Bresenham直线生成算法子程序,子程序名分别设为DDALine,MidPointLine和BresenhamLine;
分别解释直线生成算法dda法、中点画线法和bresenham法的基本原理
分别解释直线生成算法dda法、中点画线法和bresenham法的基本原理DDA直线生成算法、中点画线法和Bresenham法都是计算机图形学中用于生成直线的算法。
以下是这三种算法的基本原理:1.DDA直线生成算法(Digital Differential Analyzer):DDA算法是一种基于差分运算的直线生成算法。
其基本原理是,通过计算直线起点和终点之间的差值(横向差值dx 和纵向差值dy),并根据步长来决定下一个像素点的位置。
算法首先确定差值中绝对值较大的一方作为基准,步长设为1,另一方则按比例进行调整,以保持线段的斜率不变。
在实现过程中,DDA算法需要遍历每一个像素点,根据差值的正负和大小来确定新像素点的位置。
2.中点画线法:中点画线法的基本原理是,通过计算线段上当前像素点与相邻两个像素点构成的线段与理想直线的距离,来决定下一个像素点的位置。
具体实现时,设定线段的中点为M,理想直线与线段的交点为Q。
通过比较M和Q的位置关系来确定下一个像素点:若M在Q上方,则取上方的像素点为下一个点;若M在Q下方,则取下方的像素点为下一个点;若M与Q重合,则可任意选择上方或下方的像素点。
中点画线法以中点M作为判别标志,逐点生成直线。
3.Bresenham法:Bresenham算法的原理是基于直线的斜率和截距来计算每个像素点的位置。
在计算机屏幕上,每个像素点都有一个坐标值。
Bresenham算法通过计算直线上每个像素点的坐标值来绘制直线,避免了使用浮点数运算,从而提高了计算效率。
在实现过程中,Bresenham算法根据直线的斜率以及当前像素点的位置,计算出下一个像素点的位置,并逐点绘制出直线。
实验1中点画线和Bresenham画线算法的实现
实验1中点画线和Bresenham画线算法的实现计算机图形学实验报告实验1 使用画线算法,绘制直线段一.实验目的及要求(1)掌握图形学中常用的三种画线算法:数值微分法、中点画线法和Bresenham画线算法。
(2)掌握绘制直线的程序设计方法。
(3)掌握使用文件来保存直线段的方法。
(4)掌握从文本文件中恢复出直线的方法。
二.实验内容使用VC++ 6.0开发环境,分别实现中点画线算法和Bresenham 画线算法,绘制直线(注意,不能使用VC中已有的绘制直线的函数),并以文本文件的形式保存绘制的结果,可以从文本文件中恢复出以前绘制过的直线。
三.算法设计与分析Bresenham算法绘制直线的程序(仅包含整数运算)。
void MidBresenhamLine(int x0,int y0,int x1,int y1,int color) {int dx,dy,d,UpIncre,DownIncre,x,y;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}x=x0;y=y0;dx=x1-x0;dy=y1-y0;d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while(x<=x1){putpixel(x,y,color);X++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;}}四.程序调试及运行结果的自我分析与自我评价// testView.cpp : implementation of the CT estView class#include "stdafx.h"#include "test.h"#include "testDoc.h"#include "testView.h"#include // ifstream、ofstream等位于其中#include#include // string类型需要#include "DlgInput.h" //CDlgInput类的头文件using namespace std;#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif// CTestViewIMPLEMENT_DYNCREATE(CTestView, CView)BEGIN_MESSAGE_MAP(CTestView, CView)//{{AFX_MSG_MAP(CTestView)ON_COMMAND(ID_MENUITEM32771, OnMenuitem32771)ON_COMMAND(ID_MENUBRESENHAMLINE, OnMenubresenhamline) ON_COMMAND(ID_MENUCLEARVIEW, OnMenuclearview)ON_COMMAND(ID_FILE_OPEN, OnFileOpen)ON_COMMAND(ID_FILE_SA VE, OnFileSave)//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview) END_MESSAGE_MAP()// CTestView construction/destructionCTestView::CTestView(){// TODO: add construction code herem_nFlag = -1; // 不是任何绘图类型}CTestView::~CT estView(){}BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}// CTestView drawingvoid CTestView::OnDraw(CDC* pDC){CTestDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereif(1==m_nFlag) // 中点画线{MidPointLine(m_X0, m_Y0, m_X1, m_Y1, RGB(255,0,0) );}else if(2==m_nFlag) // Bresenham画线{BresenhamLine(m_X0, m_Y0, m_X1, m_Y1, RGB(0,255,0) );}}// CTestView printingBOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}// CTestView diagnostics#ifdef _DEBUGvoid CTestView::AssertValid() const{CView::AssertValid();}void CTestView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CTestDoc* CTestView::GetDocument() // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CT estD oc)));return (CT estDoc*)m_pDocument;}#endif //_DEBUG// CTestView message handlersvoid CTestView::OnMenuitem32771(){// TODO: Add your command handler code herem_nFlag = 1; // 中点画线CDlgInput dlg;if(IDOK==dlg.DoModal()){m_X0=dlg.m_nX0;m_Y0=dlg.m_nY0;m_X1=dlg.m_nX1;m_Y1=dlg.m_nY1;RedrawWindow(); //重绘窗口}}void CTestView::OnMenubresenhamline(){// TODO: Add your command handler code herem_nFlag = 2; // Bresenham画线CDlgInput dlg;if(IDOK==dlg.DoModal()){m_X0=dlg.m_nX0;m_Y0=dlg.m_nY0;m_X1=dlg.m_nX1;m_Y1=dlg.m_nY1;RedrawWindow(); //重绘窗口}}// 算法: 中点画线// 输入: 起点(x0,y0),终点(x1,y1);// 输入要求x0<=x1;void CTestView::MidPointLine( int x0, int y0, int x1, int y1, int color ){CDC * pDC=GetDC();int a,b,d0,d1,d2,d3,d4,d5,d,x,y;a=y0-y1;b=x1-x0; // 之前的设置已经保证始终有x1>=x0d=2*a+b;d0=2*a-b;d1=2*a;d2=2*(a+b);d3=2*b;d4=2*(a-b);d5=a-2*b;x=x0;y=y0;pDC->SetPixel(x,y,color);if(x==x1) // 斜率k为无穷大{if(y<=y1){while(y<=y1){pDC->SetPixel(x,y,color);y++;}}else{while(y>=y1){pDC->SetPixel(x,y,color);y--;}}}// if 斜率k为无穷大else // 斜率k为有限值{// double k=-a/b;// if( k+1>1e-6 && k-1<1e-6 || fabs(k-1)<1e-6 || fabs(k+1)<1e-6) // |k|<=1(即:-1<= k <=1),与1e-6比较是浮点数比较方法if( -b<=-a && -a<=b ) // 用浮点数比较在|k|=1.0f时容易出问题,所以直接用整数比较(将斜率k转换为a与b的比较;之前的设置已经保证b为正数){if(y<=y1){while(x<x1)< p="">{if(d<0){x++;y++;d+=d2;}else{x++;d+=d1;}pDC->SetPixel(x,y,color);}}else{while(x<x1)< p="">{if(d0<0){ x++;d0+=d1;}else{ x++;y--; d0+=d4; }pDC->SetPixel(x,y,color);}}}// if( |k|<=1 )else // |k|>1{if(y<=y1){while(x<x1)< p="">{if(d<0){y++;d+=d3;}else{y++;x++;d+=d2;}pDC->SetPixel(x,y,color);}}else{while(x<x1)< p="">{if(d5<0){ x++;y--; d5+=d4;}else{y--; d5+=-2*b;}pDC->SetPixel(x,y,color);}}}// else( |k|>1 )}// else 斜率k为有限值ReleaseDC(pDC);}// 算法: Bresenham画线// 输入: 起点(x0,y0),终点(x1,y1);// 输入要求x0<=x1;void CTestView::BresenhamLine( int x0, int y0, int x1, int y1, int color ){ CDC * pDC=GetDC();int x,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while(x<=x1){ pDC->SetPixel(x,y,color);x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}void CTestView::OnMenuclearview(){// TODO: Add your command handler code here m_X0=0;m_Y0=0;m_X1=0;m_Y1=0;RedrawWindow();//重绘窗口}// 打开过去保存的文件,该文件包含直线的端点坐标void CTestView::OnFileOpen(){// TODO: 在此添加命令处理程序代码if( m_nFlag!=1 && m_nFlag!=2 ){MessageBox("请先在菜单中选择绘制直线的方法!","提示",MB_ICONWARNING);return;}CFileDialog dlgFile (TRUE, _T("txt"), _T(""),OFN_FILEMUSTEXIST| OFN_HIDEREADONL Y, _T("线段端点坐标文件(*.txt)|*.txt||"), this);if( IDOK == dlgFile.DoModal()){CString fileName = dlgFile.GetFileName();ifstream rFile;rFile.open(fileName,ios::in);if ( ! rFile.is_open() ){MessageBox("文件打开失败!","提示",MB_ICONW ARNING);return;}CString strLine0;string strLine;int nX,nY;// 起点、终点,两个坐标rFile>>strLine;strLine0 = strLine.c_str();nX = atoi( strLine0.Left( strLine0.Find(",") ) ); // 解析文件,如“220,221”表示一个点的x、y坐标nY = atoi( strLine0.Mid( strLine0.Find(",")+1 ) );m_X0 = nX;m_Y0 = nY;rFile>>strLine;strLine0 = strLine.c_str();nX = atoi( strLine0.Left( strLine0.Find(",") ) );nY = atoi( strLine0.Mid( strLine0.Find(",")+1 ) );m_X1 = nX;m_Y1 = nY;RedrawWindow();rFile.close();}}// 保存当前视图上绘制的所有直线的端点坐标void CTestView::OnFileSave(){// TODO: 在此添加命令处理程序代码CFileDialog dlgFile(FALSE, _T("txt"), _T(""), OFN_OVERWRITEPROMPT, _T("线段端点坐标文件(*.txt)|*.txt||"), this);if( IDOK == dlgFile.DoModal()) // 保存文件{CString strFileName = dlgFile.GetFileName(); // 包含完整路径的文件名称ofstream wFile;wFile.open(strFileName,ios::out|ios::ate|ios::app);if ( ! wFile.is_open() ){MessageBox(strFileName+"文件创建失败!","提示",MB_ICONW ARNING);return;}wFile<<m_x0<<","<<m_y0<<="">wFile<<m_x1<<","<<m_y1<<="">五.实验心得及建议实验心得:Bresenham算法是一种很方便很实用很简单的算法,它对任意斜率的直线段具有通用性。
DDA算法 中点画线算法 Bresenham算法
实验1直接绘制实验(提示:#表示Project的编号,##表示Project题目)学号姓名上交时间1.问题描述如何利用OpenGL实现直线光栅化的DDA算法、中点画线算法和Bresenham算法2.算法描述DDA算法:据直线公式y = kx + b来推导出来的,其关键之处在于如何设定单位步进,即一个方向的步进为单位步进,另一个方向的步进必然是小于1。
中点划线法:在画直线段的过程中,当前像素点为(xp ,yp ),下一个像素点有两种可选择点P1(xp +1,yp )或P2(xp +1,yp +1)。
若M=(xp +1,yp +0.5)为P1与P2之中点,Q 为P理想直线与x=xp +1垂线的交点。
当M在Q的下方,则P2应为下一个像素点;M在Q的上方,应取P1为下一个像素点。
Bresenham算法:过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
实验结果成功运行三个算法,并且能转换出通用Bresenham算法。
3.分析与评论(分析每个算法的运行时间,对你的本实验的工作进行评论,同时也可以对老师提出建议。
)附录: Source Code(in C)#include <GL/glut.h> //需要正确安装GLUT,安装方法如预备知识中所述void myDisplay(void){glClearColor(0.0, 0.0, 0.0, 0.0);glClear(GL_COLOR_BUFFER_BIT);glColor3f (1.0f, 1.0f, 1.0f);glRectf(-0.5f, -0.5f, 0.5f, 0.5f);glBegin (GL_TRIANGLES);glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (0.0f, 1.0f);glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.8f, -0.5f);glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (-0.8f, -0.5f);glEnd ();glColor3f(1,0,0);glBegin(GL_LINE_LOOP);glVertex2f (0.0f, 0.5f);glVertex2f (0.4f, -0.25f);glVertex2f (-0.4f, -0.25f);glEnd ();glPointSize(3);glBegin (GL_POINTS);glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (-0.4f, -0.4f);glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.0f, 0.0f);glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (0.4f, 0.4f);glEnd ();glFlush();}int main(intargc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("Hello World!");glutDisplayFunc(&myDisplay);glutMainLoop();return 0;}通用算法:int Sign(int n){if(n>0) return 1;if(n==0) return 0;if(n<0) return -1;}void Bresenham(int x0,int y0,int x1,int y1,void (*setPixel)(intx,int y)){ int x,y,dx,dy,s1,s2,temp=0,interchange;x=x0; y=y0;dx=abs(x1-x0); dy=abs(y1-y0);s1=Sign(x1-x0); s2=Sign(y1-y0);if(dy>dx){temp=dx; dx=dy; dy=temp;interchange=1;}elseinterchange=0;int e=2*dy-dx;for(inti=1;i<=dx;++i){setPixel(x,y);while(e>0){if(interchange==1)x=x+s1;elsey=y+s2;e=e-2*dx;}if(interchange==1)y=y+s2;elsex=x+s1;e=e+2*dy;}}(以上是实验报告的最小要求,以后可以会根据各个Project的不同情况增加内容。
直线生成算法 DDA画线算法、中点画线算法、Bresenham画线算法
101x x y y x y k --=∆∆=Bkx y i i +=()()111111<+==∆∆+=∆++=+∆+=+=++++k ky y x let xk y y x k B kx B x x k B kx y i i i i i i i i ()111111>+==∆∆+-=-=+++k k x x y let ky k B k y k B k y x i i i i i 实验一、直线生成算法DDA 画线算法一 .名称:DDA 画线算法;二 . 算法分析:1.设直线两端点为:P1(x1,y1)及 P0(x0,y0),2.则直线斜率3.则直线方程为4.当 k <1 , x 每增加1,y 最多增加1(或增加小于1)。
5.当 k>1 ,y 每增加1,x 最多增加1 (或增加小于1) 。
y ix i y i +1 x i +1三.算法实现:void CHuayahuaView::OnDda() //DDA画直线{// TODO: Add your command handler code hereCDC* pdc1 = GetDC();int color = RGB(255,0,0);int x1=10,y1=20,x2=200,y2=200;double k=(y2-y1)*1.0/(x2-x1);//k<1;double y=y1;for(int i=x1;i<=x2;i++){pdc1->SetPixel(i,(int)(y+0.5),color);y=y+k;}ReleaseDC(pdc1);}四:程序截图:中点画线算法一.实验名称:中点画线算法二.算法分析:直线方程直线将二维空间划分为三个区域:如F(x,y)=0, 则(x,y) 在直线上如F(x,y)<0, 则(x,y)在直线下方如F(x,y)>0, 则(x,y)在直线上方条件: a= -(y1-y0)b=(x1-x0)c= -B(x1-x0)三.代码实现:void CHuayahuaView::MidPointLine(){// TODO: Add your command handler code hereCDC* pdc1 = GetDC();int color = RGB(255,0,0);int x1=30,y1=50,x2=200,y2=100;//斜率;int x,y,a,b,d,d0,d1,d2;a=y2-y1;b=x2-x1;d=2*a+b;d1=2*a;d2=2*(a+b);x=x1,y=y1;pdc1->SetPixel(x,(int)(y+0.5),color);while(x < x2){if(d>0){x++;y++;d+=d2;}else{x++;d+=d1;}pdc1->SetPixel(x,(int)(y+0.5),color);}ReleaseDC(pdc1);}四.程序截图:Bresenham画线算法一.算法名称:Bresenham画线算法二.算法分析:定义决策变量d = d+k (0<k<1)设0<k<1,如直线上的一点为(x,y),则点,为: (x+1,y) (d<0.5) 或(x+1,y+1)(d>=0.5) 当d>1时,让以证0<=d<1d0=0定义决策变量d = d+k (0<k<1)设0<k<1,如直线上的一点为( x,y), 则下一点为: (x+1,y) (d<0.5) 或(x+1,y+1)(d>=0.5) 当d>1时, 让d=d-1,以保证0<=d<1定义决策变量e = d-0.5 (0<k<1),e0 = -0.5则下一点为:(x+1,y) (e<0) 或(x+1,y+1)(e>=0) 当e >0时, 让e=e-1, (重新初始化误差项)由于算法只用到误差项的符号,为了改用整数以避免除法,可以作如下替换:e = 2*e*dx定义决策变量e = 2*e*dx, e0 = - dx;e=e +2*dy则下一点为: (x+1,y) (e <0) ;或(x+1,y+1)(e >=0) 当e >0时, 让e= e - dx, (重新初始化误差项)三.算法实现:void CHuayahuaView::Breshnham(){// TODO: Add your command handler code hereCDC* pdc2 = GetDC();int color = RGB(255,0,0);int x1=50,y1=50,x2=200,y2=150;int x,y,dx,dy,e;dx=x2-x1;dy=y2-y1;e=-dx;x=x1;y=y1;for(int i=0;i<=dx;i++){pdc2->SetPixel(x,(int)(y+0.5),color);x++;e=e+2*dy;if(e>=0){y++;e=e-2*dx;}}ReleaseDC(pdc2);}四:程序运行截图:。
贵州大学计算机图形学实验报告----直线生成算法
贵州大学计算机图形学实验报告学院:计算机科学与信息学院专业:软件工程班级:102班优点:用整数加法代替了DDA数值微分法中的浮点数加法及取整运算,大大提高了算法的效率。
缺点:在计算d的符号时,需要做4个加法和2个乘法改进:因为d是x和y的线性函数,因此可采用增量计算。
通过计算可得对于|k|<=1的情况d的初值为a+0.5b,当d>=0,M在L上方,增量d1为a;当d<0,M在L下方,增量d2为a+b。
对于|k|>1的情况d的初值为0.5a+b,当d>=0,M在L下方,增量d1为b;当d<0,M在L上方,增量d2为a+b。
三、Bresenham划线算法该算法是计算机图形学领域中使用最为广泛的直线扫描转换算法,该划线算法类似与中点划线算法,也是由误差项符号决定下一个像素右边点还是右上点。
基本原理:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
该算法的优点在于增量计算,使得对于每一列只要检查一个误差项的符号,就可以确定该列所求的像素。
根据直线的斜率来确定变量在x 或y方向递增一个单位。
另一个方向y或x的增量为0或1,它取决于实际直线与最接近网格点位置的距离。
这一距离称为误差。
由以上原理,为方便计算,令e = d-0.5,e的初值为-0.5,增量为k。
当 e>=0时,取当前像素(xi,yi)的右上方像素(xi+1,yi+1),e减小1,而当e<0时,更接近于右方像素(xi+1,yi)。
Bresenham算法的分析:优点:高效,巧妙地采用了e = d-0.5,e的初值为-0.5来简化运算,把e和0.5的比较转化成了e和0的比较,使得每次画点只需考虑误差项增量的符号即可。
斜率显示:中点划线算法斜率显示:Bresenham算法斜率显示:注:可根据教学需要对以上栏目进行增减。
表格内容可根据内容扩充。
DDA法,中点法,Bresenham法画直线
实验名称 DDA 法,中点法,Bresenham 法画直线一、实验目的学会用DDA 法,中点法,Bresenham 法这三种思想画直线,同时,对画直线的操作有一定的了解。
二、实验原理及内容1. DDA 法的基本思想如下:已知过端点P0(x0,y0) , P1(x1,y1)的直线段L :y=kx+b ,直线斜率为k=(y1-y0)/x1-x0 ,从x 的左端点x0开始,向x 右端点步进。
步长=1(个象素),计算相应的y 坐标y=kx+b ;取象素点(x, round(y))作为当前点的坐标。
2. 中点法的基本思想如下:当前象素点为(xp, yp) 。
下一个象素点为P1 或P2 。
设M=(xp+1, yp+0.5),为p1与p2之中点,Q 为理想直线与x=xp+1垂线的交点。
将Q 与M 的y 坐标进行比 较。
当M 在Q 的下方,则P2 应为下一个象素点;M 在Q 的上方,应取P1为下一点。
构造判别式:d=F(M)=F(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c ,其中a=y0-y1, b=x1-x0, c=x0y1-x1y0当d<0,M 在L(Q 点)下方,取右上方P2为下一个象素;当d>0,M 在L(Q 点)上方,取右方P1为下一个象素;当d=0,选P1或P2均可,约定取P1为下一个象素;但这样做,每一个象素的计算量是4个加法,两个乘法。
采用增量算法改进如下:d 是xp, yp 的线性函数,因此可采用增量计算,提高运算效率。
若当前象素处于d 0情况,则取正右方象素P1 (xp+1, yp), 要判下一个象素位置,应计算d1=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)+c=d+a ; 增量为a ,若d<0时,则取右上方象素P2 (xp+1, yp+1)。
要判断再下一象素,则要计算d2= F(xp+2, yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b ;增量为a +b画线从(x0, y0)开始,d 的初值d0=F(x0+1, y0+0.5)=F(x0, y0)+a+0.5b =a+0.5b 。
计算机图形学 实验 数值微分(DDA)法、中点画线法、Bresenham算法
最终,Bresenham算法也是每个象素,需一个整数算法,其优点是可以用于其他二次曲线。
三、实验内容:
1.DDA画线法:
void DDALine(CDC *pdc,int x0,int x1,int y0,int y1,int color)
{
int a,b,d,d1,d2,x,y;
a=y0-y1,b=x1-x0,d=2*a+b;
d1=2*a,d2=2*(a+b);
x=x0,y=y0;
pdc->SetPixel(x,y,color);
while(x<x1)
{
if(d<0)
{
x++;
y++;
d+=d1;
}
else
{
x++;
d+=d2;
}
pdc->SetPixel(x,y,color);
2.掌握数值微分(DDA)法、中点画线法、Bresenham算法的基本步骤;
二、实验原理:
1.数值微分(DDA)法
已知过端点的直线段L:y=kx+b,直线斜率为
从x的左端点开始,向x右端点步进。步长=1(个象素),计算相应的y坐标y=kx+b;取象素点(x, round(y))作为当前点的坐标。
2.中点画线法
}
}
void CMy2View::On1()
{
// TODO: Add your command handler code here
int x0,x1,y0,y1,color;
三种直线段绘制方法:DDA算法、B算法和中点分割法
三种直线段绘制⽅法:DDA算法、B算法和中点分割法⼀、综述三种直线段绘制⽅法:DDA算法、B算法和中点分割法。
在MFC环境中测试上述三种算法并对⽐分析三种算法的误差及效率。
⼆、程序框架MFC程序:cgDrawLineView.h为视图层的头⽂件,负责声明各种成员变量和成员函数;cgDrawLineView.cpp为视图层的源⽂件,负责实现直线的三种绘制、误差分析及messageBox显⽰。
CSelectControl.h为窗⼝⾯板中的按键及⽂本定义成员变量及成员函数。
CSelectControl.cpp实现⾯板的功能,如点击按键绘制图像、分析误差等。
三、算法描述1. DDA算法原理:根据直线的微分⽅程计算dy=m*dx(1)将给定端点作为输⼊参数;(2)初始化,初值加上0.5确保精度;(3)⽐较起⽌点⽔平和垂直的差值⼤数作为计算步数steps;(4)每步计算dx,dy分别为差数除以steps;(5)从起始点开始确定相邻两点间的增量并进⾏递推计算。
2. B算法(1)设定interChange、Xsign、Ysign便于判断位置并计算误差初值e = 2 * min - max;(min和max分别为⽔平距离和垂直距离的最值)(2)设置点(Xi, Yi) 的颜⾊值,并求下⼀误差ei+1;如果 ei >= 0 则ei+1 =ei+m-1;否则ei+1 = ei + m;(3)根据不同象限,确定X和Y变化符号的正负,进⾏下⼀次(2)(3)循环直⾄结束;3. 中点分割法原理:递归⼆分法结束条件:|P1-P2|<=1(1)将直线段求中点坐标,若可以细分,则进⾏⼀次递归;(2)如果中点坐标⽆法继续递归,则设置坐标的颜⾊值;(3)执⾏⾄所有点都完成了颜⾊值的设置,程序结束。
四、处理流程主要处理流程为:1. 在DrawLineView.h中定义double ddaError, ddaSmooth, bError, bSmooth, mpError, mpSmooth;void MidPointline(CDC* pDC, float x1, float y1, float x2, float y2);2. 在DrawLineView.cpp中完成初始赋值、函数具体实现以及误差、时间、平滑度计算和messageBox的弹出3. 在IDD_SELECTCONTROL中新添加button(MidPoint Line)且添加类向导,完善void CCSelectControl::OnClickedMidpointline()函数4. 在DrawLineView.cpp中完成pDoc->m_opMode ==2的调⽤程序基本完成五、运⾏结果当点击DDA Line时调⽤DDA直线⽣成函数当点击B Line时调⽤B直线⽣成函数当点击MidPoint时调⽤中点分割直线⽣成函数点击Comparision时先后调⽤三种直线⽣成函数,并弹出调⽤时间(受限于电脑运⾏速度原因只运⾏单次,计算次数for循环注释掉了,如有需要可取消注释,重新⽣成结果)、误差和光滑其中,RunTime值越低表⽰效率越⾼,Error越⼩表⽰误差越⼩,Smooth越⼩表⽰直线越光滑。
分别解释直线生成算法dda法、中点画线法和bresenham法的基本原理。
分别解释直线生成算法dda法、中点画线法和bresenham法
的基本原理。
一、DDA(Digital Differential Analyzer)法
DDA法是一种基于像素的直线生成算法,其基本原理是通过在直线的每个像素点上应用微分关系来计算出该点的位置。
具体来说,首先选择一个起始点,然后在直线上每隔一个像素点进行微分计算,得到该点相对于前一个点的增量。
在直线的终点处,由于没有前一个点的信息,需要使用特殊的方法进行处理。
DDA法生成的线条在视觉上较为平滑,且无需进行线条绘制。
二、中点画线法
中点画线法是一种基于连续点的直线生成算法,其基本原理是每隔一定数量的点在直线上绘制一个点,以生成直线。
该算法的优点是计算量较小,适用于实时性要求较高的场景。
但是,由于该算法生成的线条不够平滑,因此在一些对线条质量要求较高的场景下可能无法满足要求。
三、Bresenham法
Bresenham法是一种基于二进制运算的直线生成算法,其基本原理是通过比较相邻像素之间的灰度级差异来决定线条的绘制。
算法首先确定直线的起点和终点,然后根据灰度级差异的大小和二进制运算的特点,确定在直线上绘制点的位置。
Bresenham法生成的线条在视觉上较为清晰,且具有较好的连续性。
同时,由于该算法采用了二进制运算,因此在处理大量数据时具有较高的效率。
总结:DDA法、中点画线法和Bresenham法是常用的直线生成算法,每种算法都有其适用的场景和优缺点。
在实际应用中,需要根据具体需求和场景选择合适的算法,以达到最佳的直线生成效果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int a,b,d,d1,d2,x,y;
a=y0-y1,b=x1-x0,d=2*a+b;
d1=2*a,d2=2*(a+b);
x=x0,y=y0;
pdc->SetPixel(x,y,color);
while(x<x1)
{
if(d<0)
{
x++;
y++;
d+=d1;
}
else
{
x++;
d+=d2;
}
pdc->SetPixel(x,y,color);
设直线方程为:,其中k=dy/dx。因为直线的起始点在象素中心,所以误差项d值k,即d=d+k。一旦d≥1,就把它减去1,这样保证d在0、1之间。
当d≥0.5时,最接近于当前象素的右上方象素(),而当d<0.5时,更接近于右方象素()。为方便计算,令e=d-0.5,e的初值为-0.5,增量为k。
int x0,y0,x1,y1,color;
x0=111;
y0=111;
x1=138;
y1=138;
color=RGB(0,0,255);
CClientDC dc(this);
DDALine(&dc,x0,x1,y0,y1,color);
}
2.Midpoint中点画线法:
void Midpoint_Line(CDC *pdc,int x0,int y0,int x1,int y1,int color)
若d<0时,则取右上方象素P2(xp+1, yp+1)。要判断再下一象素,则要计算
d2= F(xp+2, yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b;增量为a+b。
3.Bresenham算法
过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。
{
float k=1.0*(y1-y0)/(x1-x0);
int x=0,int y=y0;
for(x=0;x<=x1;x++)
{
pdc->SetPixel(x,y,color);
y=y+k;
}
}
void CMy3View::On2()
{
// TODO: Add your command handler code here
}
}
void CMy2View::On1()
{
// TODO: Add your command handler code here
int x0,x1,y0,y1,color;
x0=111;
y0=111;
x1=138;
y1=138;
color=RGB(255,0,0);
CClientDC dc(this);
int x0,x1,y0,y1,color;
x0=111;
y0=111;
x1=138;
y1=138;
color=RGB(0,255,0);
CClientDC dc(this);
Bresenham_Line(&dc,x0,y0,x1,y1,color);
}
四、实验总结:
在程序代码段的第一句话中一定要注明“CDC *pdc”,否则会出现错误,相应的,在for循环或while循环语句中的“(x,y,color)”前面要改为“pdc->SetPixel”。在程序第二段的倒数第二句“CClientDC dc(this);”一定不能漏写,最后一句中,括号里一定要注意不能漏写了“&dc”。另外,还需注意分号的使用,有的地方时分号,有的地方时逗号,一定要注意区分。
Midpoint_Line(&dc,x0,y0,x1,y1,color);
}
3.Bresenham画线法:
void Bresenham_Line(CDC *pdc,int x0,int y0,int x1,int y1,int color)
{
int x,y,dx,dy,i;
float k,e;
dx=x1-x0,dy=y1-y0,k=dy/dx;
1.数值微分(DDA)法
已知过端点的直线段L:y=kx+b,直线斜率为
从x的左端点开始,向x右端点步进。步长=1(个象素),计算相应的y坐标y=kx+b;取象素点(x, round(y))作为当前点的坐标。
2.中点画线法
当前象素点为(xp, yp)。下一个象素点为P1或P2。
设M=(xp+1, yp+0.5),为p1与p2之中点,Q为理想直线与x=xp+1垂线的交点。将Q与M的y坐标进行比较。
当d=0,选P1或P2均可,约定取P1为下一个象素;
但这样做,每一个象素的计算量是4个加法,两个乘法。
d是xp, yp的线性函数,因此可采用增量计算,提高运算效率。
若当前象素处于d0情况,则取正右方象素P1(xp+1, yp),要判下一个象素位置,应计算d1=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)=d+a;增量为a。
XXXXXXXX
实验名称数值微分(DDA)法、中点画线法、Bresenham算法
实验时间年月日
专业姓名学号
预习操作座位号
教师签名总评
一、实验目的:
1.了解数值微分(DDA)法、中点画线法、Bresenham算法的基本思想;
2.掌握数值微分(DDA)法、中点画线法、Bresenham算法的基本步骤;
二、实验原理:
e=-0.5,x=x0,y=y0;
for(i=0;i<=dx;i++)
{
pdc->SetPixel(x,y,color);
x=x+1;
e=e+k;
if(e>=0)
{
y++,e=e-1;
}
}
}
void CMy1View::On1()
{
// TODO: Add your command handler code here
当e≥0时,取当前象素(xi,yi)的右上方象素();而当e<0时,更接近于右方象素()。
最终,Bresenham算法也是每个象素,需一个整数算法,其优点是可以用于其他二次曲线。
三、实验内容:
1.DDA画线法:
void DDALine(CDC *pdc,int x0,int x1,int y0,int y1,int color)
当M在Q的下方,则P2应为下一个象素点;
当M在Q的上方,应取P1为下一点。
构造判别式:d=F(M)=F(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c,其中a=y0-y1, b=x1-x0, c=x0y1-x1y0。
当d<0,M在L(Q点)下方,取右上方P2为下一个象素;
当d>0,M在L(Q点)上方,取右方P1为下一个象素;