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

合集下载

计算机图形学,直线,圆,二维变换

计算机图形学,直线,圆,二维变换

实验一、直线的生成实验目的:1、掌握DDA直线画法、中点画线法和Bresenham画线法2、掌握VC++简单程序设计方法实验内容:根据提供的程序框架,修改部分代码,完成画一条直线的功能(中点画线法或者Bresenham画线法任选一),只要求实现在第一象限内的直线。

实验步骤和方法:首先启动Visual C++ 6.0(注意,其它版本程序无法正确编译),文件(file)→打开工作空间(open workspace)。

打开实验12用基本图形生成\基本图形生成.dsw。

在fileview窗口,source file下,双击直线生成view.cpp,或者classview窗口下,cmyview类下相应的函数,按注释改写下列函数:void CMyView::OnDdaline() (此为DDA生成直线)void CMyView::OnBresenhamline()(此为Bresenham画直线)void CMYView::OnMidPointLine()(此为中点画线法)程序代码说明:1、直线的两个端点,由对话框输入,给定程序已经完成输入代码。

2、SetPixel的用法:COLORREF SetPixel(int x, int y, COLORREF crColor);//x,y为坐标点。

COLORREF SetPixel(POINT point, COLORREF crColor);//point为坐标点。

3、本实验事先提供DDA话直线的函数示范(红色部分是重点,其它部分可以不看)中点画直线函数和BresenHam画直线函数由同学们参照dda直线的示例函数自己完成。

//以下为DDA画直线的源程序float x,y,dx,dy,k;dx=(float)(xb-xa);dy=(float)(yb-ya);k=dy/dx;x=xa;y=ya;if(abs(k)<1){for (x=xa;x<=xb;x++){pdc->SetPixel(x, int(y+0.5),COLOR);y=y+k;}}if(abs(k)>=1){for(y=ya;y<=yb;y++){pdc->SetPixel(int(x+0.5),y,COLOR);x=x+1/k;}}//DDA画直线结束//以下为中点画直线的源程序float a,b,d1,d2,d,x,y;a=ya-yb,b=xb-xa,d=2*a+b;d1=2*a,d2=2*(a+b);x=xa,y=ya;pdc->SetPixel(x,y,COLOR);while(x<xb){ if(d<0){x++,y++,d+=d2;}else {x++,d+=d1;}pdc->SetPixel(x,y,COLOR);}//中点画直线结束//以下为Bresenham画直线的源程序int i,s1,s2,interchange;float f,x,y,deltax,deltay,temp; x=xa;y=ya;deltax=abs(xb-xa);deltay=abs(yb-ya);if(xb-xa>=0)s1=1;else s1=-1;if(yb-ya>=0)s2=1;else s2=-1;if(deltay>deltax){ temp=deltax;deltax=deltay;deltay=temp;interchange=1;}else interchange=0;f=2*deltay-deltax;pdc->SetPixel(x,y,COLOR);for(i=1;i<=deltax;i++){ if(f>=0){if(interchange==1) x+=s1;else y+=s2;pdc->SetPixel(x,y,COLOR);f=f-2*deltax;}else {if(interchange==1) y+=s2;else x+=s1;f=f+2*deltay;}}}//Bresenham画直线结束实验二、圆的生成(中点和Bresenham法)实验目的:1、掌握bresenham画圆的算法。

基本图形生成算法-直线圆弧

基本图形生成算法-直线圆弧

1 / max( x , y )
广东工业大学机电学院图学与数字媒体工程系
计算机图形学基础:基本图形生成算法——直线及圆弧的扫描转换 直线的扫描转换——数值微分法
绘制直线时,要确定一个方向的增量为单位增量,即确定 画线的基本步进方向,另一个方向的增量由直线的斜率决
定。确定基本步进方向的依据是理想直线的斜率k。
DDA算法是一种增量算法,优点是直观、易于实现;
缺点是要做浮点运算和舍入取整,不利于硬件实现。
广东工业大学机电学院图学与数字媒体工程系
计算机图形学基础:基本图形生成算法——直线及圆弧的扫描转换 直线的扫描转换——数值微分法
斜率<=1时,以x为基本 步进方向,x方向每次步 进增量为1。
斜率>1时,以y为基 本步进方向,y方向 每次步进增量为1。
第二象限 第四象限
走笔 +Y 走笔 -Y Fk+1=Fk-|xA |
走笔 -X 走笔 +X Fk+1=Fk+|yA |
逐点比较法绘制直线.doc
广东工业大学机电学院图学与数字媒体工程系
计算机图形学基础:基本图形生成算法——直线及圆弧的扫描转换
【注】递推公式的作用: 意义:简化计算过程,提高效率。 原则:尽可能以加减法代替乘除法。 方法:用当前点的偏差推算出走笔方向,并计算出下一
Fi 1 xA yi 1 y A xi 1
即第i+1点的偏差判别式为:
xA ( yi 1) y A xi Fi x A
广东工业大学机电学院图学与数字媒体工程系
计算机图形学基础:基本图形生成算法——直线及圆弧的扫描转换 直线的扫描转换——逐点比较法
各象限的判别式

计算机图形学-三种直线生成算法及圆的生成算法

计算机图形学-三种直线生成算法及圆的生成算法

计算机科学与技术学院2013-2014学年第一学期《计算机图形学》实验报告班级:110341C学号:110341328姓名:田野教师:惠康华成绩:实验(一):平面图形直线和圆的生成一、实验目的与要求1.在掌握直线和圆的理论基础上,分析和掌握DDA生成直线算法、中点生成直线算法、Bresenham生成直线算法、中点画圆算法、Bresenham圆生成算法。

2.熟悉VC6.0MFC环境,利用C语言编程实现直线和圆的生成。

3.比较直线生成三种算法的异同,明确其优点和不足。

同时了解圆的生成算法适用范围。

二、实验内容1.掌握VC6.0环境中类向导和消息映射函数的概念,并且为本次实验做好编程准备工作。

2. 用C语言进行编程实现上述算法,并且调试顺利通过。

3. 在MFC图形界面中显示不同算法下的图形,并且注意对临界值、特殊值的检验。

完成后保存相关图形。

三、算法分析➢DDA直线生成算法描述:1)给定一直线起始点(x0,y0)和终点(x1,y1)。

分别计算dx=x1-x0,dy=y1-y0。

2)计算直线的斜率k=dy/dx。

当|k|<1时转向3);当|k|<=1时,转向4);3)当x每次增加1时,y增加k。

即(xi,yi)→(xi+1,yi+k)。

直到xi增加到x1。

并且每次把得到的坐标值利用系统函数扫描显示出来。

但要注意对y坐标要进行int(y+0.5)取整运算。

结束。

4)对y每次增加1时,x增加1/k,即(xi,yi)→(xi+1/k,yi+1)。

直到yi增加到y1. 并且每次把得到的坐标值利用系统函数扫描显示出来。

但要注意对x坐标要进行int(x+0.5)取整运算。

结束。

➢中点生成算法描述:算法基本思想:取当前点(xp,yp),那么直线下一点的可能取值只能近的正右方点P1(xp+1,yp)或者P2(xp+1,yp+1)。

为了确定好下一点,引入了这两点中的中点M(xp+1,yp+0.5)。

这时可以把改点带入所在直线方程,可以观察该中点与直线的位置关系。

计算机图形学第二讲 直线和圆的生成

计算机图形学第二讲 直线和圆的生成

直线DDA算法思想
选定x2-x1和y2-y1中较大者作为步进方向(假设x2-x1较大),取该方向 上的增量为一个象素单位(△x=1),然后利用公式计算另一个方向的增量 (△y=△x· m=m)。通过递推公式,把每次计算出的(xi+1,yi+1)经取整后送到 显示器输出,则得到扫描转换后的直线。 之所以取x2-x1和y2-y1中较大者作为步进方向,是考虑沿着线段分布的 象素应均匀,这在下图中可看出。
直线Bresenham算法描述
我们来分析公式d1-d2=2m(xi+1)-2yi+2b-1 (1)当此值为正时,d1>d2,说明直线上理论点离(xi+1,yi+1)象素较近, 下一个象素点应取(xi+1,yi+1)。 (2)当此值为负时,d1<d2,说明直线上理论点离(xi+1,yi)象素较近,则 下一个象素点应取(xi+1,yi)。 (3)当此值为零时,说明直线上理论点离上、下两个象素点的距离相等, 取哪个点都行,假设算法规定这种情况下取(xi+1,yi+1)作为下一个象素点。 因此只要利用(d1-d2)的符号就可以决定下一个象素点的选择。
另外,算法实现中还应注意直线的生成方向,以决定Δx及Δy是取正值还 是负值。
直线DDA算法实现
Void DDALine(int x1,int y1,int x2, int y2,int color) { int x; float k,y=y1; k=1.0*(y2-y1)/(x2-x1); for(x=x1;x<=x2;x++) { putpixel(x, (int)(y+0.5),color); y=y+k; } }

直线和圆弧的生成算法

直线和圆弧的生成算法

第3章直线和圆弧的生成算法3.1直线图形的生成算法数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。

当我们对直线进行光栅化时,需要在显示器有限个像素中,确定最佳逼近该直线的一组像素,并且按扫描线顺序,对这些像素进行写操作,这个过程称为用显示器绘制直线或直线的扫描转换。

由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。

本节我们介绍一个像素宽直线绘制的三个常用算法:数值微分法(DDA、中点画线法和Bresenham算法。

3.1.1逐点比较法3.1.2数值微分(DDA)法设过端点P o(x o , y°)、R(X1 , y1)的直线段为L( P0 , R),则直线段L的斜率为—沁生要在显示器显示厶必须确定最佳逼近Z的掃素集合。

我们从L的起点P0的横坐标X o向L的终点R的横坐标X1步进,取步长=1(个像素),用L 的直线方程y=kx+b计算相应的y坐标,并取像素点(x,round( y))作为当前点的坐标。

因为:y i+1 = kX i+1+b= 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 DDALi ne(int xO,i nt yO,i nt x1,i nt y1,i nt color){ int x ;float dx, dy, y, k ;dx = x1-x0 ;dy=y1-y0 ;k=dy/dx, ;y=yO;for (x=xO ;x< x1 ;x++){ drawpixel (x, i nt(y+0.5), color);y=y+k;}}注意:我们这里用整型变量color表示像素的颜色和灰度。

直线和圆弧的生成算法

直线和圆弧的生成算法

第3章直线和圆弧的生成算法3.1直线图形的生成算法数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。

当我们对直线进展光栅化时,需要在显示器有限个像素中,确定最优逼近该直线的一组像素,并且按扫描线顺序,对这些像素进展写操作,这个过程称为用显示器绘制直线或直线的扫描转换。

由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。

本节我们介绍一个像素宽直线绘制的三个常用算法:数值微分法〔DDA〕、中点画线法和Bresenham算法。

3.1.1逐点比拟法3.1.2数值微分(DDA)法设过端点P0(x0,y0)、P1(x1,y1)的直线段为L(P0,P1),如此直线段L的斜率L的起点P0的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个像素),用L的直线方程y=kx+b计算相应的y坐标,并取像素点(x,round(y))作为当前点的坐标。

因为:y i+1= kx i+1+b= 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) y0 0 01 02 13 14 2图3 直线段的扫描转换注意:上述分析的算法仅适用于|k| ≤1的情形。

计算机图形学作业(中点法画直线和八分画圆法)

计算机图形学作业(中点法画直线和八分画圆法)
y=y1;y1=y0;y0=y;
}
x=x0;y=y0;
dx=x1-x0;dy=y1-y0;
d=dx-2*dy;
up=2*x-2*y;
down=-2*dy;
while(x<=x1){
pDC->SetPixel(x,y,color);
x++;
if(d<0){
y++;
d+=up;
}
else d+=down;
}
}
void CMy213View::OnButton32772()
{
CDC *pDC;
pDC=this->GetDC();
int x0=50,y0=50,x1=300,y1=300,color=333;
MidBresenhamLine(pDC,x0,y0,x1,y1,color);
this->ReleaseDC(pDC);
计算机图形学作业中点法画直线和八分画圆法计算机图
1、中点法画直线:
void MidBresenhamLine(CDC *pDC,int x0,int y0,int x1,int y1,int color){
int dx,dy,){
x=x1;x1=x0;x0=x;
}
x++;
}
}
void CmbView::Onbbb()
{
CDC *pDC;
pDC=this->GetDC();
int r=60,color=333;
MidBresenhamCircle(pDC,r,color);
this->ReleaseDC(pDC);

计算机图形学-直线、圆、椭圆的生成

计算机图形学-直线、圆、椭圆的生成

2014-9-5
中点画线法
假设直线方程为:ax+by+c=0 其中a=y0-y1, b=x1-x0, c=x0y1-x1y0 由常识知:
F x, y 0 F x, y 0 F x, y 0 点在直线上面 点在直线上方 点在直线下方
P2
Q
P=(xp,yp) P1
2014-9-5 浙江大学计算机图形学 28
圆的扫描转换
圆的扫描转换是在屏幕像素点阵中确定最佳逼近于 理想圆的像素点集的过程。圆的绘制可以使用简单方程 画圆算法或极坐标画圆算法,但这些算法涉及开方运算 或三角运算,效率很低。主要讲解仅包含加减运算的顺 时针绘制 1/8 圆的中点 Bresenham 算法原理,根据对称 性可以绘制整圆 。
2014-9-5 浙江大学计算机图形学 22
设图中xi列上已用(xi,yir)作为表示直线的点, 又设B点是直线上的点,其坐标为(xi+1,yi+1),显然 下一个表示直线的点( xi+1,yi+1,r)只能从图中的C 或者D点中去选。设A为CD边的中点。 若B在A点上面 则应取D点作为( xi+1,yi+1,r),否则应取C点。
P=(xp,yp ) P1 浙江大学计算机图形学
16
中点画线法

若d<0->M在直线下方->取P2; 此时再下一个象素的判别式为 d2= F(xp+2, yp+1.5) =a(xp+2)+b(yp+1.5)+c = a(xp +1)+b(yp +0.5)+c +a +b =d+a+b ; 增量为a+b
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

信息与计算科学专业基础课ComputerReport Of course 计算机图形学课程实验报告实验题目设计算法绘制直线与圆班级姓名学号指导教师日期实验说明 试验目的: 掌握直线和圆的基本生成算法思想,并上机编程实现相应的算法。

试验地点: 教九楼401 数学系机房实验要求(Direction): 1. 每个学生单独完成;2.开发语言为TurboC 或C++,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。

实验内容实验题一实验题目1).用DDA 法在屏幕上画一条具有三个像素宽的直线段L1。

要求:(1)直线段L1的两个端点坐标和画线颜色都要求可以随机输入;(2)要求输出直线段L1上的各点坐标;(3)画出直线的同时要求标明两端点坐标。

2).将课堂所讲的斜率0<K<1的中点画线算法推广到斜率K>1、-1<K<0和K<-1的情况,编写一通用的中点画线算法。

实验目的和意义1.了解如何利用C 语言和图形函数进行绘图;2. 熟悉并掌握C 语言的图形模式控制函数,图形屏幕操作函数,以及基本图形函数;3. 通过对Turbo C 进行图形程序设计的基本方法的学习,能绘制出简单的图形;4. 熟悉并掌握DDA 法在屏幕上画一条具有三个像素宽的直线段L1以及通用的中点画线算法。

通过DDA 法及用的中点画线算法,了解图形系统初始化、图形系统关闭和图设计算法绘制直线与圆实验2形模式的控制,并熟练运用图形坐标的设置,包括定点、读取光标以及图形颜色的设置。

程序制作步骤(包括算法思想、算法流程图等)1.自动搜索显示器类型和显示模式,初始化图形系统,通过printf 、scanf 语句控制线段的端点坐标和画线颜色的自由输入;2. DDAline:设直线之起点为(x1,y1),终点为(x2,y2),则斜率k 为: 则有:⑴.可通过计算由x 方向的增量x ∆引起y 的改变生成直线。

由1i i y y y +=+∆ (i y 为直线上某步的初值)则21121i i i y y y y x y k x x x +-=+∆=+∆- ⑵.也可通过计算由y 方向的增量y ∆引起x 的改变生成直线。

由1i i x x x +=+∆(i x 为直线上某步的初值)则:211211i i i x x x x y x y y y k+-=+∆=+∆- :⑴.假定X 坐标为p x 的各像素点中,与直线最近点已确定为(,)p p x y (用实心小圆表示),那么下一个与直线最近的象素点只能是正右方的1(1,)p p p x y +或右上方2(1,1)p p p x y ++两者之一。

⑵. 再以M 表示P1与P2的中点,即(1,0.5)p p M x y =++又设Q 是理想直线与垂直线1p x x =+的交点 。

显然有:①.当M 在Q 的下方,则P2 离直线 近,应取为下一个象素点;②.当M 在Q 的上方,则P1离直线 近,应取为下一个象素点。

③.当M 和Q 重合,则P 1和P2离直线 一样近,两者均可取为下一个象素点主程序xyx x y y k ∆∆=--=12121+=p x xDDA算法#include ""#include <>#include <>#include <>#include <>DDAline(int x1, int y1, int x2, int y2, int c) {float delta_x = 0;float delta_y = 0;float x = 0;float y = 0;int dx= 0;int dy = 0;int steps = 0;int k = 0;dx=x2-x1;dy=y2-y1;if (abs(dx)>abs(dy)){steps=3*abs(dx);}else{steps=3*abs (dy);}delta_x=(float)dx / (float)steps;delta_y=(float)dy / (float)steps;x=float(x1);y=float(y1);for (k=1; k<=steps;k++){putpixel(int(x+, int(y+, c);x+=delta_x;y+=delta_y;}return 0;}void main(){char t[100] = {0};int x1 = 0;int y1 = 0;int x2 = 0;int y2 = 0;int c = 0;void dda_line(int x1,int y1,int x2,int y2,int c);int graphdriver=DETECT,graphmode;initgraph(&graphdriver,&graphmode,"D:\\TC"); /*初始化图形系统*/printf("输入两端点坐标:\n");scanf("<%d,%d>,<%d,%d>",&x1,&y1,&x2,&y2);printf("输入画线颜色:\n");scanf("%d",&c);DDAline(x1,y1,x2,y2,c);sprintf(t,"(%d,%d)",x1,y1);outtextxy(x1,y1,t);sprintf(t,"(%d,%d)",x2,y2);outtextxy(x2,y2,t);getch(); /*等待按一键结束*/closegraph(); /*关闭图形系统,回到文本模式*/ }中点画线算法#include <>#include <>#include <>#include <>#include ""MidpointLine(int x1,int y1,int x2,int y2,int c){int a = 0;int b = 0;int d1 = 0;int d2 = 0;int d = 0;int x = 0;int y = 0;float m = 0;if (x2<x1){d=x1;x1=x2;x2=d;d=y1;y1=y2;y2=d;}a=y1-y2;b=x2-x1;if (b==0){m=-1*a*100;}else{m=(a/(x1-x2)); }x=x1;y=y1;putpixel(x,y,c);if (m>=0 && m<=1){d=2*a+b;d1=2*a;d2=2*(a+b);while (x<x2){if (d<=0){x++;y++;d+=d2;}else{x++;d+=d1;}putpixel(x,y,c);}}else if (m<=0 && m>=-1){d=2*a-b;d1=2*a-2*b;d2=2*a;while (x<x2){if (d>0){x++;y--;d+=d1;}else{x++;d+=d2;}putpixel(x,y,c);}}else if (m>1){d=a+2*b;d1=2*(a+b);d2=2*b;while (y<y1){if (d>0){x++;y++;d+=d1;}else{y++;d+=d2;}putpixel(x,y,c);}}else{d=a-2*b;d1=-2*b;d2=2*(a-b);while (y>y1){if (d<=0){x++;y--;d+=d2;}else{y--;d+=d1;}putpixel(x,y,c);}}return 0;}void main(){char t[100] = {0};int x1 = 0;int y1 = 0;int x2 = 0;int y2 = 0;int c = 0;int graphdriver=DETECT,graphmode;initgraph(&graphdriver,&graphmode,"D:\\TC"); /*初始化图形系统*/printf("输入两端点坐标:\n");scanf("<%d,%d>,<%d,%d>",&x1,&y1,&x2,&y2);printf("输入画线颜色:\n");scanf("%d",&c);MidpointLine(x1,y1,x2,y2,c);sprintf(t,"(%d,%d)",x1,y1);outtextxy(x1,y1,t);sprintf(t,"(%d,%d)",x2,y2);outtextxy(x2,y2,t);getch(); /*等待按一键结束*/closegraph(); /*关闭图形系统,回到文本模式*/ }运行结果图DDA算法图算法运行结果截图图算法运行结果截图中点画线算法图中点画线算法当k<=1时运行结果截图图中点画线算法当k<=1时运行结果截图图中点画线算法当0<k<1时运行结果截图图中点画线算法当0<k<1时运行结果截图图中点画线算法当k=-1时运行结果截图图中点画线算法当k=-1时运行结果截图图中点画线算法当-1<k<0时运行结果截图图中点画线算法当-1<k<0时运行结果截图图中点画线算法当k<-1时运行结果截图实验题二实验题目1).参考课堂所讲过的斜率为0~1和大于1的Bresenham画线程序,将该算法程序扩展到任一八分圆坐标空间图,从而形成一般的Bresenham画线算法。

并利用Bresenham画线算法画出4条不同颜色、不同斜率的直线段L1、L2、L3、L4。

要求:(1)4条直线段L1、L2、L3、L4的斜率K1、K2、K3、K4满足:0<K1<1,-1<K2<0, K3<-1,K4>1;(2)直线段的两个端点坐标和画线颜色都要求可以随机输入。

相关文档
最新文档