当前位置:文档之家› 计算机图形学 直线的生成算法的实现

计算机图形学 直线的生成算法的实现

计算机图形学  直线的生成算法的实现
计算机图形学  直线的生成算法的实现

实验二 直线的生成算法的实现

班级 08信计2班 学号 59 姓名 分数

一、实验目的和要求

1.理解直线生成的基本原理。

2.掌握几种常用的直线生成算法。

3.利用Visual C++实现直线生成的DDA 算法。

二、实验内容

1.了解直线的生成原理,尤其是Bresenham 画线法原理。

2.掌握几种基本的直线生成算法:DDA 画线法、Bresenham 画线法、中点画线法。

3.利用Visual C++实现直线生成的DDA 算法,在屏幕上任意生成一条直线。

三、实验步骤

1.直线的生成原理:

(1)DDA 画线法也称数值微分法,是一种增量算法。是一种基于直线的微分方程来生成直线的方法。

(2)中点画线法原理

以下均假定所画直线的斜率[0,1]k ∈,如果在x 方向上的增量为1,则y 方向上的增量只能在01 之间。中点画线法的基本原理是:假设在x 坐标为p x 的各像素点中,与直线最近者已经确定为(,)p p P x y ,用小实心圆表示。那么,下一个与直线最近的像素只能是正右方的1(1,)p p P x y +,或右上方的2(1,1)p p P x y ++,用小空心圆表示。以M 为1P 和2P 的中点,则M 的坐标为(1,0.5)p p x y ++。又假设Q 是理想直线与垂直线1p x x =+的交点。显然,若M 在Q 的下方,则2P 离直线近,应取2P 为下一像素点;若M 在Q 的上方,则1P 离直线近,应取1P 为下一像素点。

(3)B resenham 画线法原理

直线的中点Bresenham 算法的原理:每次在主位移方向上走一步,另一个方向上走不走步取决于中点偏差判别式的值。

给定理想直线的起点坐标为P0(x0,y0),终点坐标为P1(x1,y1),则直线的隐函数方程为:

0b kx y y)F(x,=--= (3-1)

构造中点偏差判别式d 。

b

x k y y x F y x F d i i i i M M -+-+=++==)1(5.0)5.0,1(),(

??

?≥<+=+)0( )0( 11

d y d y y i i i

(1) 当d<0时

b x k y y x F d i i i i i -+-+=++=+)2(5.1)5.1,2(1

k

d k b x k y i i i -+=-+-+-+=11)1(5.0

⑵ 当d ≥0时

b x k y y x F d i i i i i -+-+=++=+)2(5.0)5.0,2(1

k

d k b x k y i i i -=--+-+=)1(5.0

2.实现前面所述的各种直线生成算法,包括DDA 算法、中点生成算法、Bresenham 生成算法等。程序运行后的菜单界面如图2-1所示。

图2-1 直线生成图形的程序运行界面

首先创建工程名为“基本图形的生成与填充”的单文档应用程序框架,操作步骤如下:

(1)创建单文档应用程序框架。

启动Visual C++,选择“文件/新建”菜单命令,在弹出的新建对话框中单击“工程”标签;选择.MFC AppWizard(exe),在“工程名称”编辑框中输入“基本图形的生成与填充”(也可以使用英文名称),选择所要存放的位置后,单击“确定”按钮,出现Stept1对话框;选择“单个文档”选项,单击“下一步”按钮,在接着的Stept2~Stept5中,均可以直接单击“下一步”按钮完成应用程序框架的构建。也可以在Stept1步选择“单文档”(Single document )后,直接单击“完成”按钮完成。

(2)编辑菜单资源。

在工作区中的Resource V iew 标签中,单击Menu 项左边的“+”,然后双击其子项IDR _MAINFRAME ,弹出编辑主菜单项,根据表1中定义的菜单项资源来编辑菜单,如图2-2

所示。

图2-2 编辑主菜单项

(3)添加消息处理函数。

利用类向导(Class Wizard)为应用程序添加与菜单项相关的消息处理函数。右击菜单项标题,选择“建立类向导…”,在弹出的MFC ClassWizard窗口中,选择Message Maps 标签,在Class Name栏中选择CMyView,根据表2建立消息映射函数,如图2-3所示。MFC ClassWizard会自动完成有关的函数声明。

图2-3 添加消息处理函数

(4)添加程序代码。

在CMyView.cpp文件中相应的位置添加各算法的程序代码,在Visual C++的MFC中绘制图形,一般可以调用一个“CDC”类,从CDC开始,添加代码。

添加代码如下:

//DDA算法生成直线,起点(x0,y0),终点(x1,y1)。

void CMyView::OnDdaline()

{

CDC *pDC=GetDC();

int x0=100,y0=100,x1=300,y1=200,c=RGB(255,0,0);

int x,y,i;

float dx,dy,k;

dx=(float)(x1-x0);

dy=(float)(y1-y0);

k=dy/dx;

x=x0;

y=y0;

if(abs(k)<1)

{

for(;y<=y1;y++)

{

pDC->SetPixel(x,int(y+0.5),c);

y=y+k;

}

}

if(abs(k)>=1)

{

for(;y<=y1;y++)

{

pDC->SetPixel(int(x+0.5),y,c);

x=x+1/k;

}

}

ReleaseDC(pDC);

}

//中点算法生成直线

void CMyView::OnMidpointline()

{

CDC *pDC=GetDC();

int x0=100,y0=100,x1=400,y1=300,c=RGB(0,0,0);

float a,b,d1,d2,d,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,c);

while(x

{

if(d<0) {x++;y++;d+=d2;}

else {x++;d+=d1;}

pDC->SetPixel(x,y,c);

}

ReleaseDC(pDC);

}

//Bresenham算法生成直线

void CMyView::OnBresenhamline()

{

CDC *pDC=GetDC();

int x0=100,y0=100,x1=500,y1=600,color=RGB(0,0,255);

int i,x,y,dx,dy;

float k,e;

dx=x1-x0;

dy=y1-y0;

e=-dx;

x=x0;

y=y0;

for(i=0;i<=dx;i++)

{

pDC->SetPixel(x,y,color);

x++;

e+=2*dy;

if(e>=0) {y++;e=e-2*dx;}

}

ReleaseDC(pDC);

}

(5)编译连接生成可执行程序,运行该程序。

仔细检查上述各个操作步骤,核对以上信息,点击调试按钮,调试程序准确无误后即可完整运行该程序。

四、实验结果分析

运行该程序后,运行程序后,我们可以得到如图2-1的界面,分别单击菜单中的“直线生成”项的“DDA算法生成直线”、“中点算法生成直线”、“Bresenham算法生成直线”,可以得到相应的直线:DDA算法得到的是红色线段,中点生成算法得到的是黑色线段,Bresenham 生成算法得到的是蓝色线段,如图2-4所示。

图2-4 直线的生成效果图

备注:DDA法就是根据直线的斜率来计算出下一个y值,经取整后以确定下一个像素点,

因为在进行取整运算,这就难以避免出现所取像素点片在实际直线某一侧的情况。

计算机图形学输出直线实验报告

六盘水师范学院计科系本科班计算机图形学实验报告 系别:计科系 课程名称:计算机图形学 班级:本科 学号:114077031057 学生姓名:郑月儒 一、实验目的 1、了解和使用开发环境; 2、熟悉MFC上机操作步骤; 3、熟悉基本图形函数的使用。 二、实验环境 1、操作系统Windows7旗舰版 2、Microsoft Visual C++6.0 3、PC 三、实验人数 5人 四、实验内容 在屏幕上绘制一条直线。 五、实验步骤 (1)进入Microsoft Visual C++6.0集成开发环境后,选择“文件-新建”菜单,弹出“新建”对话框。单击“工程”标签,打开其选项卡,在其左边的列表框中选择MFC AppWizard(EXE)工程类型,在

“工程名称”文本框输入工程名,在“位置”中选择工程路径。如果是第一个工程文件,则必须创建一个新的工作区,选择“创建新的工作空间”,在“平台”编辑框中选择“Win32”。 (2)单击“确定”按钮,现实“MFC应用程序向导-步骤1”对话框,选择“单文档”选项。 (3)单击“完成”按钮,系统弹出“新建工程信息”对话框。(4)单击“确定”按钮,就完成了应用程序的自动生成,在指定的目录下生成了应用程序框架所必需的全部文件,并且可以以直接运行。 (5)选择“组建-执行”。因为是第一次执行,没有生成可执行文件.EXE,提示是否生成,选择“是”,则系统进行编译及连接,生成可执行文件,并运行。、 (6)在窗口左边工作区“FileView”标签中,选择graphicView.cpp 文件,在voidCGraphicView::OnDraw(CDC*pDC)函数中添加如下代码:pDC->SetPixel(100,100,RGB(0,0,0)); pDC->MoveTo(0,0); pDC->LineTo(1000,415); (7)运行程序,得到实验结果。 六、实验效果(含程序运行主要截图)

计算机图形学裁剪算法详解

裁剪算法详解 在使用计算机处理图形信息时,计算机部存储的图形往往比较大,而屏幕显示的只是图的一部分。因此需要确定图形中哪些部分落在显示区之,哪些落在显示区之外,以便只显示落在显示区的那部分图形。这个选择过程称为裁剪。最简单的裁剪方法是把各种图形扫描转换为点之后,再判断各点是否在窗。但那样太费时,一般不可取。这是因为有些图形组成部分全部在窗口外,可以完全排除,不必进行扫描转换。所以一般采用先裁剪再扫描转换的方法。 (a)裁剪前 (b) 裁剪后 图1.1 多边形裁剪 1直线段裁剪 直线段裁剪算法比较简单,但非常重要,是复杂图元裁剪的基础。因为复杂的曲线可以通过折线段来近似,从而裁剪问题也可以化为直线段的裁剪问题。常

用的线段裁剪方法有三种:Cohen-Sutherland,中点分割算法和梁友栋-barskey 算法。 1.1 Cohen-Sutherland裁剪 该算法的思想是:对于每条线段P1P2分为三种情况处理。(1)若P1P2完全在窗口,则显示该线段P1P2简称“取”之。(2)若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。(3)若线段既不满足“取”的条件,也不满足“弃”的条件,则在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。 为使计算机能够快速判断一条直线段与窗口属何种关系,采用如下编码方法。延长窗口的边,将二维平面分成九个区域。每个区域赋予4位编码CtCbCrCl.其中各位编码的定义如下:

图1.2 多边形裁剪区域编码图5.3线段裁剪 裁剪一条线段时,先求出P1P2所在的区号code1,code2。若code1=0,且code2=0,则线段P1P2在窗口,应取之。若按位与运算code1&code2≠0,则说明两个端点同在窗口的上方、下方、左方或右方。可判断线段完全在窗口外,可弃之。否则,按第三种情况处理。求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段在窗口外,可弃之。在对另一段重复上述处理。在实现本算法时,不必把线段与每条窗口边界依次求交,只要按顺序检测到端点的编码不为0,才把线段与对应的窗口边界求交。 Cohen-Sutherland裁减算法 #define LEFT 1 #define RIGHT 2 #define BOTTOM 4

DDA直线生成算法

实验报告 课程名称计算机图形学 实验名称DDA直线生成算法编程的实现实验类型验证型 实验地点计通学院304实验日期2010-03-29指导教师 专业 班级 学号 姓名 成绩 辽宁石油化工大学计算机与通信工程学院

实验报告说明 1、封面内容 (1)课程名称:实验所属的课程的名称。 (2)实验名称:要用最简练的语言反映实验的内容。要求与实验指导书中相一致。 (3)实验类型:说明是验证型实验、设计型实验、创新型实验还是综合型实验。 2、正文内容 实验报告的正文内容须包括以下内容: (1)实验目的:目的要明确,要抓住重点,符合实验指导书中的要求。 (2)实验内容:说明本实验的主要内容。 (3)实验原理:简要说明本实验项目所涉及的理论知识。 (4)实验环境:实验用的软硬件环境(配置)。 (5)实验方案:对于验证性型实验,写明依据何种原理、操作方法进行实验;对于设计型和综合型实验,写明依据何种原理、操作方法进行实验,并画出硬件组成图、软件流程图、设计思路和设计方法,再配以相应的文字说明;对于创新型实验,除符合设计型和综合型实验要求外,还应注明其创新点、特色。(6)实验步骤:写明实验的实施步骤,包括实验过程中的记录、数据。 (7)实验结果与分析:写明实验的最终结果,并对结果进行分析,做出结论。(8)实验中遇到的问题及解决方法:写明实验过程中遇到的问题及所采取的解决方法。 (9)实验总结(在封底上):写出对本次实验的心得体会、思考和建议。

实验原理:已知线段的起点坐标()11x y ,终点坐标()22x y ,直线的点斜 式方程为:y m x b =?+,斜率和截距分别为:2121y y m x x -= - , 11b y m x =-? 。沿x 的增量为x ?,沿y 的增量为y ?,即: 1x y m ?= ??,y m x ?=??。当1m ≤时,取x 为一个像素单位长,即x 每次增加一个像素,然后利用公式计算相应的y 值:1k k k y y y y m x -=+?=+??,相反1m >时,可以通过质量y ?来计算相应的x 值:1k k k x x x x m y -=+?=+??。 实验内容:新建一个Win32 Application 的典型“Hello World ”程序,工程 命名为:DDA 直线生成算法,打开DDA 直线生成算法.cpp 文件, 在里面加入代码: void DDA_line(HDC hdc) { double x,y,dx,dy,L,x1=100,x2=400,y1=100,y2=400; if(abs(x2-x1)>=abs(y2-y1)) L=abs(x2-x1); else L=abs(y2-y1); dx=(x2-x1)/L; dy=(y2-y1)/L; x=x1,y=y1; for(int k=1;k<=L;k++) { SetPixel(hdc,x,y,RGB(255,0,255)); x=x+dx; y=y+dy; Sleep(10); } } 实验结果:调用程序运行得出一下结果:

Bresenham的直线生成算法和整圆生成算法完整代码

以下是Bresenham的直线生成算法和整圆生成算法,已调试过,没有任何问题。Bresenham直线生成算法 #include "stdio.h" #include "graphics.h" Bresenham_line(x0,y0,x1,y1,color) int x0,y0,x1,y1,color; { int x,y,dx,dy, i; float k,e; dx=x1-x0;dy=y1-y0; k=(dy*1.0)/dx; e=-0.5; x=x0; y=y0; for (x=x0; x<=x1; x++) { putpixel(x,y,color); e=e+k; if(e>=0) { y++;e=e-1;} } } int main() { int x0,y0,x1,y1,c; int driver=DETECT,mode=0; initgraph(&driver,&mode,"c:\\tc"); setbkcolor(BLUE); setcolor(YELLOW); printf("input x0,y0,x1,y1,c"); scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&c); Bresenham_line(x0,y0,x1,y1,c); getch(); closegraph(); } 当取e=2*dy-dx时,可以消除浮点和除法运算 #include "stdio.h" #include "graphics.h" Bresenham_line(x0,y0,x1,y1,color)

int x0,y0,x1,y1,color; { int x,y,dx,dy, i,e; float k; dx=x1-x0;dy=y1-y0; k=(dy*1.0)/dx; e=2*dy-dx; x=x0; y=y0; for (x=x0; x<=x1; x++) { putpixel(x,y,color); e=e+2*dy; if(e>=0) { y++;e=e-2*dx;} } } int main() { int x0,y0,x1,y1,c; int driver=DETECT,mode=0; initgraph(&driver,&mode,"c:\\tc"); setbkcolor(BLUE); setcolor(YELLOW); printf("input x0,y0,x1,y1,c"); scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&c); Bresenham_line(x0,y0,x1,y1,c); getch(); closegraph(); }

计算机图形学实验一_画直线

大学实验报告 学院:计算机科学与技术专业:计算机科学与技术班级:计科131

如果 d<0,则M在理想直线下方,选右上方P1点; 如果 d=0,则M在理想直线上,选P1/ P2点。 由于d是xi和yi的线性函数,可采用增量计算提高运算效率。 1.如由pi点确定在是正右方P2点(d>0).,则新的中点M仅在x方向加1,新的d值为: d new=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c 而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c d new=d old+a= d old-dy 2.如由pi点确定是右上方P1点(d<0),则新的中点M在x和y方向都增加1,新的d值为 d new=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c 而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c d new=d old+a+b= d old-dy+dx 在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。d的初始值: d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2 F(x0,y0)=0,(x0,y0)在直线上。 为了消除d的分数,重新定义 F(x,y)=2(ax+by+c) 则每一步需要计算的d new 是简单的整数加法 dy=y1-y0,dx=x1-x0 d0=-2dy+dx d new=d old-2*dy,当 d old>=0 d new=d old-2(dy-dx),当d old<0 Bresenham画线算法 算法原理: 与DDA算法 相似,Bresenham 画线算法也要在 每列象素中找到 与理想直线最逼 近的象素点。 根据直线的 斜率来确定变量 在x或y方向递 增一个单位。另 一个方向y或x

计算机图形学 直线的生成算法的实现

实验二 直线的生成算法的实现 班级 08信计2班 学号 59 姓名 分数 一、实验目的和要求 1.理解直线生成的基本原理。 2.掌握几种常用的直线生成算法。 3.利用Visual C++实现直线生成的DDA 算法。 二、实验内容 1.了解直线的生成原理,尤其是Bresenham 画线法原理。 2.掌握几种基本的直线生成算法:DDA 画线法、Bresenham 画线法、中点画线法。 3.利用Visual C++实现直线生成的DDA 算法,在屏幕上任意生成一条直线。 三、实验步骤 1.直线的生成原理: (1)DDA 画线法也称数值微分法,是一种增量算法。是一种基于直线的微分方程来生成直线的方法。 (2)中点画线法原理 以下均假定所画直线的斜率[0,1]k ∈,如果在x 方向上的增量为1,则y 方向上的增量只能在01 之间。中点画线法的基本原理是:假设在x 坐标为p x 的各像素点中,与直线最近者已经确定为(,)p p P x y ,用小实心圆表示。那么,下一个与直线最近的像素只能是正右方的1(1,)p p P x y +,或右上方的2(1,1)p p P x y ++,用小空心圆表示。以M 为1P 和2P 的中点,则M 的坐标为(1,0.5)p p x y ++。又假设Q 是理想直线与垂直线1p x x =+的交点。显然,若M 在Q 的下方,则2P 离直线近,应取2P 为下一像素点;若M 在Q 的上方,则1P 离直线近,应取1P 为下一像素点。 (3)B resenham 画线法原理 直线的中点Bresenham 算法的原理:每次在主位移方向上走一步,另一个方向上走不走步取决于中点偏差判别式的值。 给定理想直线的起点坐标为P0(x0,y0),终点坐标为P1(x1,y1),则直线的隐函数方程为: 0b kx y y)F(x,=--= (3-1) 构造中点偏差判别式d 。 b x k y y x F y x F d i i i i M M -+-+=++==)1(5.0)5.0,1(),(

计算机图形学实验—中点算法画直线

计算机图形学实验报告 班级:软件1102 姓名:夏明轩 学号:201109020221

中点算法的线段光栅化 一、设计思想和算法流程 1.假定直线斜率0 P 2离直线更近更近->取P 2 。 M 在Q 的上方-> P 1离直线更近更近->取P 1 M 与Q 重合, P 1、P 2任取一点。 问题:如何判断M 与Q 点的关系? 由常识知:若y=kx+b; F(x,y)=y-kx-b;则有 ()()()?????<>=点在直线下方 0,点在直线上方0,点在直线上面0,y x F y x F y x F 假设直线方程为:ax +by +c=0 (y=(-a/b)x-c/b) 通过两点不能唯一确定a,b,c, 取 a=y 0-y 1, b=x 1-x 0, c=x 0y 1-x 1y 0 F(x,y)=ax +by +c=b(y-(-a/b)x-c/b); ()()()?????<>=点在直线下方0,点在直线上方0 ,点在直线上面0,y x F y x F y x F 则有 ∴欲判断M 点是在Q 点上方还是在Q 点下方,只需把M 代入F (x ,y ),并检查它的符号。构造判别式:d=F(M)=F(x p +1,y p +0.5)=a(x p +1)+b(y p +0.5)+c 当d<0,M 在直线(Q 点)下方,取右上方P 2; 当d>0,M 在直线(Q 点)上方,取右方P 1; 当d=0,选P 1或P 2均可,约定取P 1; 能否采用增量算法呢?若d ≥0 ---->M 在直线上方->取P1;此时再下一个象素的判别式为 d 1=F(x p +2, y p +0.5) =a(x p +2)+b(y p +0.5)+c = a(x p +1)+b(y p +0.5)+c +a =d+a ; 增量为a 若d<0 ------>M 在直线下方->取P2;此时再下一个象素的判别式为 d 2= F(x p +2, y p +1.5) =a(x p +2)+b(y p +1.5)+c = a(x p +1)+b(y p +0.5)+c +a +b =d+a+b ;

计算机图形学图形的几何变换的实现算法

实验二图形的几何变换的实现算法 班级 08 信计 学号 59 姓名 _____ 分数 _____ 一、 实验目的和要求: 1、 掌握而为图形的基本几何变换,如平移,旋转,缩放,对称,错切变换;< 2、 掌握OpenG 冲模型变换函数,实现简单的动画技术。 3、 学习使用OpenGL 生成基本图形。 4、 巩固所学理论知识,加深对二维变换的理解,加深理解利用变换矩阵可 由简单图形得到复杂图形。加深对变换矩阵算法的理解。 编制利用旋转变换绘制齿轮的程序。编程实现变换矩阵算法,绘制给出形体 的三视图。调试程序及分析运行结果。要求每位学生独立完成该实验,并上传实 验报告。 二、 实验原理和内容: .原理: 图像的几何变换包括:图像的空间平移、比例缩放、旋转、仿射变换和图像插值。 图像几何变换的实质:改变像素的空间位置,估算新空间位置上的像素值。 图像几何变换的一般表达式:[u,v ]=[X (x, y ),Y (x, y )],其中,[u,v ]为变换后图像 像素的笛卡尔坐标, [x, y ]为原始图像中像素的笛卡尔坐标。这样就得到了原始图像与变 换后图像的像素的对应关系。 平移变换:若图像像素点(x, y )平移到(x x 。,y ■ y 。),则变换函数为 u = X (x, y ) =x 沟, v 二丫(x, y ) = y ■ y 。,写成矩阵表达式为: 比例缩放:若图像坐标 (x,y )缩放到(S x ,s y )倍,则变换函数为: S x ,S y 分别为x 和y 坐标的缩放因子,其大于1表示放大, 小于1表示缩小。 旋转变换:将输入图像绕笛卡尔坐标系的原点逆时针旋转 v 角度,则变换后图像坐标为: u COST 内容: :u l :Sx k ;0 其中,x 0和y 0分别为x 和y 的坐标平移量。 其中,

(1)直线生成算法.doc

课程名称:计算机图形学指导教师:罗晓辉 上机实践名称:基本图形(直线)生成算法 年级:2008 姓名:孔广波 学号:312008********* 上机实践成绩: 上机实践日期:2011-4-10 实验一: 直线生成算法 上机实践报告 一、实验目的 理解直线生成的基本原理,掌握儿种常见的直线生成算法,利用Microsoft Visual C++6.0实现直线生成的DDA算法。 二、实验内容: 1)了解直线的生成原理。 2)掌握儿种基本的直线生成算法:DDA画线法、Bresenham画线法、中点画线法。 3)利用Microsoft Visual C++6.0实现直线生成的DDA算法,在屏幕上任意生成一条直线。 三、实验步骤: 1)预习教材关于直线的生成原理。 2)仿照教材关于直线生成的DDA算法,使用Microsoft Visual C++6.0实现该算法。 3)调试、编译、运行程序。 四、实验分析、源程序和结果: (1.1)中点算法分析: 中点画线算法原理示意图

直线斜率:k属于[0, 1] 线段的隐式方程:F(x,y) = ax + by + c = 0 ((x0 , y0), ( xl , yl )为两端点,式中a = yO - yl , b = xl - xO , c = xO * yl - xl * yO) 直线上方的点:F(x , y) > 0 直线下方的点:F ( x , y ) < 0 构造判别式:d = F(M) = F(Xp+l,Yp + 0.5) 由d>0, V0 可判定下一个象素,d 的初始值:d0 = F( X0 + 1 , Y0 + 0.5 ) = F( X0 , Y0 ) + a + 0.5b 因(X0, YO)在直线上,F(X0 , YO ) = 0,所以,dO = a + 0.5b (1.2)具体实现代码: void CGView::Line_DDA(long plxjong ply,long p2x,long p2y,CDC *pDC)〃画直线算法实现 ( int a,b,del 1 ,del2,d,x,y; b=p2x-plx; a=ply-p2y; d=2*a+b; dell=2*a; del2=2*(a+b); x=plx; y=piy; pDC->SetFixel(x,y,mJPenColor); while(xSetPixel(x,y-2,m_lPenColor); pDC->SetPixel(x,y-1 ,m_lPenColor); pDC->SetPixeI(x,y,m_lPenColor); pDC->SetPixel(x,y+1 ,m_IPenColor); pDC->SetPixel(x,y,m_lPenColor);

计算机图形学用VC++画直线

实验一基本图形生成算法 实验目的: 掌握中点Bresenham绘制直线的原理 设计中点Bresenham算法 编程实现中点Bresenham算法 实验描述: 使用中点Bresenham算法绘制斜率为0≤k≤1的直线。 算法设计: 直线中点Bresenham算法 1. 输入直线的起点坐标P0(x0,y0)和终点坐标P1(x1,y1)。 2. 定义直线当前点坐标x,y、定义中点偏差判别式d、定义直线斜率k、定义像素点颜色 rgb。 3. x=x0,y=y0,计算d=0.5-k,k=(y1-y0)/(x1-x0),rgb=RGB(0,0,255)。 4. 绘制点(x,y),判断d的符号。若d<0,则(x,y)更新为(x+1,y+1),d 更新为 d+1-k;否则(x,y)更新为(x+1,y),d更新为d-k。 5. 如果当前点x 小于x1,重复步骤4,否则结束。 源程序: 1)// TestView.h #include "InputDlg.h"//对话框头文件 class CTestView : public CView { ….. } 2)//TestView.cpp #define ROUND(a) int(a+0.5) //四舍五入 ….. void CTestView::OnMbline()//菜单响应函数 { InputDlg dlg; if(dlg.DoModal()==IDOK) { AfxGetMainWnd()->SetWindowText(":直线中点Bresenham算法"); RedrawWindow(); Mbline(dlg.m_x0, dlg.m_y0, dlg.m_x1, dlg.m_y1); } } void CTestView::Mbline(double x0, double y0,double x1,double y1) //直线中点Bresenham函数{ CClientDC dc(this); COLORREF rgb=RGB(0,0,255); //定义直线颜色为蓝色 double x,y,d,k; x=x0;y=y0;k=(y1-y0)/(x1-x0);d=0.5-k;

OpenGL-实验2直线生成算法实现教学文案

实验2 直线生成算法实现 1.实验目的 理解基本图形元素光栅化的基本原理, 掌握一种基本图形元素光栅化算法, 利用0penGL 实现直线光栅化的DDA算法。 2.实验内容 (1)根据所给的直线光栅化的示范源程序, 在计算机上编译运行, 输出正确结果。 (2)指出示范程序采用的算法, 以此为基础将其改造为中点线算法或Bresenham算法,写 入实验报告。 (3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告。 (4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。 3.实验原理 示范代码原理DDA算法。下面介绍OpenGL画线的一些基础知识和glutReshapeFunc()函数。 (1)数学上的直线没有宽度,但0penGL的直线则是有宽度的。同时, OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。可以认为, OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。这里的线由一系列顶点顺次连接而成, 有闭合和不闭合两种。 前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢? 是依次画出来,还是连成线? 或者构成一个多边形? 或是做其他事情? 为了解决这一问题, OpenGL要求:指定顶点的命令必须包含在glBegin函数之后, glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。 例如: glBegin(GL P0INTS) , glVertex2f(0.0f, 0.0f); glVertex2f(0.5f, 0.0f); glEnd(); 则这两个点将分别被画出来。如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点, OpenGL将会画出一条直线。还可以指定更多的顶点, 然后画出更复杂的图形。另一方面, glBegin支持的方式除了GL_POINTS和GL_LINES,还有GL LINE STRIP、GL LINE L0〇P、GL TRIANGLES、GL TRIANGLE STRIP、GL TRIANGLE_FAN等几何图元。 (2) 首次打开窗口、移动窗口和改变窗口大小时, 窗口系统都将发送一个事件, 以通知程序员。如果使用的是GLUT,通知将自动完成,并调用向glutReshapeFunc注册的函数。该函数必须完成下列工作: ①重新建立用作新渲染画布的矩形区域。 ②定义绘制物体时使用的坐标系。 如: void Reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h);

直线和圆弧的生成算法

第3章直线和圆弧的生成算法 3.1直线图形的生成算法 数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。当我们对直线进行光栅化时,需要在显示器有限个像素中,确定最佳逼近该直线的一组像素,并且按扫描线顺序,对这些像素进行写操作,这个过程称为用显示器绘制直线或直线的扫描转换。 由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。本节我们介绍一个像素宽直线绘制的三个常用算法:数值微分法(DDA)、中点画线法和Bresenham算法。 3.1.1逐点比较法 3.1.2数值微分(DDA)法 设过端点P0(x0 ,y0)、P1(x1 ,y1)的直线段为L(P0 ,P1),则直线段L的斜率 L的起点P 的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个像素),用L 的直线方程y=kx+b计算相应的y坐标,并取像素点(x,round(y))作为当前点的坐标。因为: y = kx i+1+b i+1 = k1x i+b+k x = y i+k x 所以,当x =1; y i+1 = y i+k。也就是说,当x每递增1,y递增k(即直线斜率)。根据这个原理,我们可以写出DDA(Digital Differential Analyzer)画线算法程序。

DDA画线算法程序: void DDALine(int x0,int y0,int x1,int y1,int color) { int x; float dx, dy, y, k; dx = x1-x0; dy=y1-y0; k=dy/dx,;y=y0; for (x=x0;x< x1;x++) { drawpixel (x, int(y+0.5), color); y=y+k; } } 注意:我们这里用整型变量color表示像素的颜色和灰度。 举例:用DDA方法扫描转换连接两点P0(0,0)和P1(5,2)的直线段。 x int(y+0.5) y+0.5 0 0 0 1 0 0.4+0.5 2 1 0.8+0.5 3 1 1.2+0.5 4 2 1.6+0.5 图3.1.1 直线段的扫描转换 注意:上述分析的算法仅适用于|k| ≤1的情形。在这种情况下,x每增加1,y最多增加1。当|k| 1时,必须把x,y地位互换,y每增加1,x相应增加1/k。在这个算法中,y与k必须用浮点数表示,而且每一步都要对y 进行四舍五入后取整,这使得它不利于硬件实现。

CG_实验2_基本图形元素(直线)生成算法的实现

实验二基本图形元素(直线)生成算法的实现 1.实验目的: 理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。 2.实验内容: (1)根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果; (2)指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告; (3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告; (4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。 3.实验原理: 示范代码原理参见教材直线光栅化一节中的DDA算法。下面介绍下OpenGL画线的一些基础知识和glutReshapeFunc()函数。

(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。 前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢?是一个一个的画出来,还是连成线?或者构成一个多边形?或是做其它事情呢?为了解决这一问题,OpenGL要求:指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。 例如: glBegin(GL_POINTS); glVertex2f(0.0f, 0.0f); glVertex2f(0.5f, 0.0f); glEnd(); 则这两个点将分别被画出来。如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。还可以指定更多的顶点,然后画出更复杂的图形。另一方面,glBegin 支持的方式除了GL_POINTS和GL_LINES,还有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,

计算机图形学-设计算法绘制直线与圆

信息与计算科学专业基础课 Computer Report Of course 计算机图形学课程实验 报告 实验题目设计算法绘制直线与圆 班级 姓名 学号 指导教师 日期

实验说明 试验目的: 掌握直线和圆的基本生成算法思想,并上机编程实现相应的算法。 试验地点: 教九楼401 数学系机房 实验要求(Direction): 1. 每个学生单独完成;2.开发语言为TurboC 或C++,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。 实验内容 实验题一 实验题目 1).用DDA 法在屏幕上画一条具有三个像素宽的直线段L1。要求:(1)直线段L1的两个端点坐标和画线颜色都要求可以随机输入;(2)要求输出直线段L1上的各点坐标;(3)画出直线的同时要求标明两端点坐标。 2).将课堂所讲的斜率01、-1

计算机图形学 圆周算法的实现

《计算机图形学实验报告》样例 实验名称:圆周画法的实现 1.实验内容 1.画出圆心坐标为(75,90)和半径为50的红色圆周 2.画出圆心坐标为(‐40,‐80)和半径为60的蓝色圆周 2.程序的基本思路和功能 先用MFC构建界面外观,然后在相应位置分别用Bresenham和DDA编辑画圆的程序然后编译运行。 3.关键代码及说明 void Circle::circleMinPoint(CDC* pDC) { xCenter = (float)(400 + x); yCenter = (float)(300 - y); //绘制圆心 drawCenter(pDC); //r = 50; //设置颜色 color = RGB(red,green,blue); float m_x = 0; float m_y = r; float d = 1.25 - r; circlePoint(m_x,m_y,pDC);

while(m_x <= m_y){ if(d<=0){ d = d + 2 * m_x + 3; }else{ d = d + 2 * ( m_x - m_y ) + 5; m_y = m_y - 1; } m_x = m_x + 1; circlePoint(m_x,m_y,pDC); } } void Circle::circleBresenham(CDC* pDC) { //确认圆心坐标 xCenter = (float)(400 + x); yCenter = (float)(300 - y); //绘制圆心 drawCenter(pDC); //r = 50; //设置颜色 color = RGB(red,green,blue); float m_x = 0; float m_y = r;

直线生成算法的实现

实验二:直线生成算法 班级 13软件+道铁1班学号 20132110050115姓名丁益 1.实验目的 a)通过实验,进一步理解直线段扫描转换的DDA算法、中点画线自算法 及bresenham算法的基本原理,掌握以上算法生成直线段的基本过程。 b)通过编程,掌握在C/C++环境下完成用DDA算法、中点画线算法及 bresenham算法对任意直线段的扫描转换,以及在C/C++环境下完成用中 点画圆及椭圆的绘制方法。 2.实验内容 c)阅读《openGL三维程序设计》(电子书)第二部分第四章,掌握OpenGL 基本建模方法,并调试其中程序。 d)参考教材第6章,编程实现整数DDA算法、中点画线法和Bresenham 画线法,绘制直线(直线宽度和线型可自定)。 2.1 DDA直线生成 2.1.1算法原理 已知过端点P0(x0,y0),P1(x1,y1)的直线段L(P0,P1),斜率为k=(y1-y0)/(x1-x0),画线过程从x的左端点x0开始,向x右端点步进,步长为1个像素,计算相应的y坐标为y=kx+B。计算y i+1 = kx i+B =kx i +B+kx =y i +kx 当x=1,y i+1=y i+k,即当x每递增1,y递增k。由计算过程可知,y与k可能为浮点数,需要取y整数,源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。 2.1.2 算法流程

2.1.3 算法实现关键代码 #include #include void Init() { glClearColor(1.0,1.0,1.0,0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0); } void lineDDA(int x0,int y0,int xEnd,int yEnd) { int dx=xEnd-x0,dy=yEnd-y0,steps,k; float xIncrement, yIncrement, x=x0, y=y0; if(fabs(dx)>fabs(dy)) steps=fabs(dx); else steps=fabs(dy); xIncrement=float(dx)/float(steps); yIncrement=float(dy)/float(steps); for(k=0;k

计算机图形学常用算法及代码大全

2.1.1 生成直线的DDA算法 数值微分法即DDA法(Digital Differential Analyzer),是一种基于直线的微分方程来生成直线的方法。 一、直线DDA算法描述: 设(x1,y1)和(x2,y2)分别为所求直线的起点和终点坐标,由直线的微分方程得 可通过计算由x方向的增量△x引起y的改变来生成直线: 也可通过计算由y方向的增量△y引起x的改变来生成直线: 式(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、已知画线的颜色:color 3、计算两个方向的变化量:dx=x2-x1 dy=y2-y1 4、求出两个方向最大变化量的绝对值: steps=max(|dx|,|dy|) 5、计算两个方向的增量(考虑了生成方向): xin=dx/steps

yin=dy/steps 6、设置初始象素坐标:x=x1,y=y1 7、用循环实现直线的绘制: for(i=1;i<=steps;i++) { putpixel(x,y,color);/*在(x,y)处,以color色画点*/ x=x+xin; y=y+yin; } 五、直线DDA算法特点: 该算法简单,实现容易,但由于在循环中涉及实型数的运算,因此生成直线的速度较慢。 //@brief 浮点数转整数的宏 实现代码 #define FloatToInteger(fNum) ((fNum>0)?static_cast(fNum+0.5):static_cast(fNum-0.5)) /*! * @brief DDA画线函数 * * @param pDC [in]窗口DC * @param BeginPt [in]直线起点 * @param EndPt [in]直线终点 * @param LineCor [in]直线颜色 * @return 无 */ void CDrawMsg::DDA_DrawLine(CDC *pDC,CPoint &BeginPt,CPoint &EndPt,COLORREF LineCor) { l ong YDis = (EndPt.y - BeginPt.y); l ong XDis = (EndPt.x-BeginPt.x); l ong MaxStep = max(abs(XDis),abs(YDis)); // 步进的步数 f loat fXUnitLen = 1.0f; // X方向的单位步进 f loat fYUnitLen = 1.0f; // Y方向的单位步进

直线生成算法——Bresenham法

直线生成算法——Bresenham法 最近的研究涉及在像素图上作直线,自己也不想花时间摸索,于是在网上找到了Bresenham的直线生成算法,有一篇博客讲得清晰明了,但是算法上有些问题,我进行了改进和移植,下面讲解Bresenham的直线生成算法时也是参考这篇博文。 1.算法简介 图1 算法思想:图1中,连接M点和N点的直线经过点B,由于是像素图,所以实际上B 点应该由A点或者C点代替。当B点更靠近A点时,选择点A(x+1,y+1);当B点更靠近C点时,选择点C(x+1,y)。 因此,当ε+m < 0.5时,绘制(x + 1, y)点,否则绘制(x + 1, y + 1)点,这里ε为累加误差,表达式为: 式中:表示在第n次计算时的值,表示在第n+1次计算时的值;m就是直线的 斜率。 由于斜率m的值有正有负,有可能为0,也可能为∞,为了避免分别讨论这些情况, 将上述公式两边都乘以dx, 并将ε*dx用ξ表示,则有 式中:表示在第n次计算时的值,表示在第n+1次计算时的值;dx为起 点和终点横坐标之差,dy为起点和终点纵坐标之差。 还需说明一点,由直线斜率的定义 故

值得注意的是,现在我们只考虑dx > dy,且x,y的增量均为正的情况,但实际上有8种不同的情况(但是算法思想不变),如图2所示 如图2 2.算法程序 前文提到的那篇博文提出了一种方法,能将这8种情况都考虑,很巧妙。但是实际应用时发现程序运行结果不是完全对,多次检查之后将程序进行了修改。 修改后的算法VB程序如下 ‘**************************************************************************** Type mypos '自定义数据类型 x As Integer y As Integer End Type ‘**************************************************************************** Function Bresenham(arr() As mypos, x1, y1, x2, y2) Dim x!, y!, dx!, dy!, ux%, uy%, eps! Dim cnt% ReDim arr(100) dx = x2 - x1 dy = y2 - y1 If dx >= 0 Then ux = 1 If dx < 0 Then ux = -1

相关主题
文本预览
相关文档 最新文档