计算机图形学设计算法绘制直线与圆讲课教案.docx
《计算机图形学设计算法绘制直线与圆讲课教案.docx》由会员分享,可在线阅读,更多相关《计算机图形学设计算法绘制直线与圆讲课教案.docx(33页珍藏版)》请在冰豆网上搜索。
计算机图形学设计算法绘制直线与圆讲课教案
计算机图形学课程实验报告
实验题目设计算法绘制直线与圆
班级
姓名
学号
指导教师
日期
@实验说明
试验目的:
掌握直线和圆的基本生成算法思想,并上机编程实现相应的算法。
试验地点:
教九楼401数学系机房
实验要求(Direction):
1.每个学生单独完成;2.开发语言为TurboC或C++,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:
题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5.自己保留一份可执行程序,考试前统一检查和上交。
@实验内容
:
实验题一
1.1实验题目
1).用DDA法在屏幕上画一条具有三个像素宽的直线段L1。
要求:
(1)直线段L1的两个端点坐标和画线颜色都要求可以随机输入;
(2)要求输出直线段L1上的各点坐标;(3)画出直线的同时要求标明两端点坐标。
2).将课堂所讲的斜率01、-11.2实验目的和意义
1.了解如何利用C语言和图形函数进行绘图;
2.熟悉并掌握C语言的图形模式控制函数,图形屏幕操作函数,以及基本图形函数;
3.通过对TurboC进行图形程序设计的基本方法的学习,能绘制出简单的图形;
4.熟悉并掌握DDA法在屏幕上画一条具有三个像素宽的直线段L1以及通用的中点画线算法。
通过DDA法及用的中点画线算法,了解图形系统初始化、图形系统关闭和图形模式的控制,并熟练运用图形坐标的设置,包括定点、读取光标以及图形颜色的设置。
1.3程序制作步骤(包括算法思想、算法流程图等)
1.自动搜索显示器类型和显示模式,初始化图形系统,通过printf、scanf语句控制线段的端点坐标和画线颜色的自由输入;
2.DDAline:
设直线之起点为(x1,y1),终点为(x2,y2),则斜率k为:
则有:
⑴.可通过计算由x方向的增量
引起y的改变生成直线。
由
(
为直线上某步的初值)则
⑵.也可通过计算由y方向的增量
引起x的改变生成直线。
由
(
为直线上某步的初值)则:
3.Midpointline:
⑴.假定X坐标为
的各像素点中,与直线最近点已确定为
(用实心小圆表示),那么下一个与直线最近的象素点只能是正右方的
或右上方
两者之一。
⑵.再以M表示P1与P2的中点,即
又设Q是理想直线与垂直线
的交点。
显然有:
①.当M在Q的下方,则P2离直线近,应取为下一个象素点;
②.当M在Q的上方,则P1离直线近,应取为下一个象素点。
③.当M和Q重合,则P1和P2离直线一样近,两者均可取为下一个象素点
1.4主程序
1.4.1DDA算法
#include"graphics.h"
#include
#include
#include
#include
DDAline(intx1,inty1,intx2,inty2,intc)
{
floatdelta_x=0;
floatdelta_y=0;
floatx=0;
floaty=0;
intdx=0;
intdy=0;
intsteps=0;
intk=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+0.5),int(y+0.5),c);
x+=delta_x;
y+=delta_y;
}
return0;
}
voidmain()
{
chart[100]={0};
intx1=0;
inty1=0;
intx2=0;
inty2=0;
intc=0;
voiddda_line(intx1,inty1,intx2,inty2,intc);
intgraphdriver=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();/*关闭图形系统,回到文本模式*/
}
1.4.2中点画线算法
#include
#include
#include
#include
#include"graphics.h"
MidpointLine(intx1,inty1,intx2,inty2,intc)
{
inta=0;
intb=0;
intd1=0;
intd2=0;
intd=0;
intx=0;
inty=0;
floatm=0;
if(x2{
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{
if(d<=0)
{
x++;
y++;
d+=d2;
}
else
{
x++;
d+=d1;
}
putpixel(x,y,c);
}
}
elseif(m<=0&&m>=-1)
{
d=2*a-b;
d1=2*a-2*b;
d2=2*a;
while(x{
if(d>0)
{
x++;
y--;
d+=d1;
}
else
{
x++;
d+=d2;
}
putpixel(x,y,c);
}
}
elseif(m>1)
{
d=a+2*b;
d1=2*(a+b);
d2=2*b;
while(y{
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);
}
}
return0;
}
voidmain()
{
chart[100]={0};
intx1=0;
inty1=0;
intx2=0;
inty2=0;
intc=0;
intgraphdriver=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();/*关闭图形系统,回到文本模式*/
}
1.5运行结果图
1.5.1DDA算法
图1.5.1DDA算法运行结果截图
图1.5.2DDA算法运行结果截图
1.5.2中点画线算法
图1.5.3中点画线算法当k<=1时运行结果截图
图1.5.4中点画线算法当k<=1时运行结果截图
图1.5.5中点画线算法当0图1.5.6中点画线算法当0图1.5.7中点画线算法当k=-1时运行结果截图
图1.5.8中点画线算法当k=-1时运行结果截图
图1.5.9中点画线算法当-1图1.5.10中点画线算法当-1图1.5.11中点画线算法当k<-1时运行结果截图
:
实验题二
2.1实验题目
1).参考课堂所讲过的斜率为0~1和大于1的Bresenham画线程序,将该算法程序扩展到任一八分圆坐标空间图,从而形成一般的Bresenham画线算法。
并利用Bresenham画线算法画出4条不同颜色、不同斜率的直线段L1、L2、L3、L4。
要求:
(1)4条直线段L1、L2、L3、L4的斜率K1、K2、K3、K4满足:
01;
(2)直线段的两个端点坐标和画线颜色都要求可以随机输入。
2).参考课堂所讲过的圆心在原点,半径为R的第一个4分圆的Bresenham画圆算法程序,利用对称性将该算法程序推广到任一四分圆,从而形成一般的Bresenham画圆算法。
并利用该算法画出一个圆心在点(xc,yc),半径为R,圆周颜色为color的圆。
要求:
(1)圆心的坐标、半径和圆周颜色都要求可以随机输入;
(2)要求利用文本输出函数显示出所画圆的圆心和半径;(3)利用四向简单种子填充算法填充该圆。
2.2实验目的和意义
1.熟悉并掌握各种斜率的Bresenham画线程序
2.熟悉并掌握C语言的图形模式控制函数,图形屏幕操作函数,以及基本图形函数;
3.熟悉并掌握Bresenham画圆算法画一个完整的圆并进行填充。
2.3程序制作步骤(包括算法思想、算法流程图等)
Bresenham画线算法思想步骤:
1.画起点(x1,y1).
2.准备画下一个点,X坐标加1,判断如果达到终点,则完成。
否则找下一个点,由图可知要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点。
2.1.如果线段ax+by+c=0与x=x1+1的交点y坐标大于(y+*y+1))/2则选右上那个点2.2.否则选右下那个点。
3.画点
4.跳回第2步
5.结束
Bresenham画线算法流程图
Bresenham画圆算法步骤:
1.首先,真实的线条是连续的,但是计算机中的线条是离散的,是由很多点组成的,那么画线的重点就是如何高效地找到这些离散的点来更好地画出想要的图形
2.实验要求用Bresenham算法实现画圆。
那么首先先要了解Bresenham算法是一种什么算法。
经过查阅,我找到Bresenham直线算法和画圆算法。
直线是圆的基础。
Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在n维光栅上最接近的点。
这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线,是计算机图形学中最先发展出来的算法。
Bresenham画圆算法又称中点画圆算法,与Bresenham直线算法一样,其基本的方法是利用判别变量来判断选择最近的像素点,判别变量的数值仅仅用一些加、减和移位运算就可以计算出来。
为了简便起见,考虑一个圆心在坐标原点的圆,而且只计算八分圆周上的点,其余圆周上的点利用对称性就可得到。
Bresenham画圆算法流程图:
2.4主程序
2.4.1Bresenham画直线
#include"graphics.h"
#include
#include
swap(int*a,int*b)
{
inttmp;
tmp=*a;
*a=*b;
*b=tmp;
}
intBresenham_line(intx1,inty1,intx2,inty2,intcolor)
{
doubledx,dy,h,x,y,t;
if(x1>x2){swap(&x1,&x2);swap(&y1,&y2);}
dx=x2-x1;
dy=y2-y1;
x=x1;y=y1;
putpixel(x,y,color);
if(dx==0)
{while(y!
=y2){putpixel(x,y,color);y++;}}
if(dy==0)
{while(x!
=x2){putpixel(x,y,color);x++;}}
if(dy!
=0&&dx!
=0)
if(dy>0)
if(dy<=dx)
{
h=2*dy-dx;
while(x!
=x2)
{
if(h<0)
h+=2*dy;
else
{
y++;
h+=2*(dy-dx);
}
putpixel(x,y,color);
x++;
}
}
else
{
h=2*dx-dy;
while(y!
=y2)
{
if(h<0)
h+=2*dx;
else
{++x;
h+=2*(dx-dy);
}
putpixel(x,y,color);
y++;
}
}
else
{
t=-dy;
if(t<=dx)
{h=2*dy+dx;
while(x!
=x2)
{
if(h<0)
{
h+=2*(dy+dx);
y--;
}
else
h+=2*dy;
putpixel(x,y,color);
x++;
}
}
else
{
h=-(2*dx*dy)-(dy*dy);
while(y!
=y2)
{
if(h<0)
h+=-(2*dx*dy);
else
{
h+=-(2*dx*dy)-(2*dy*dy);
x++;
}
putpixel(x,y,color);
y--;
}
}
}
return0;
}
main()
{
intx1,y1,x2,y2;
charc;
intcolor;
intgdriver=DETECT,gmode;
here:
//color=6;
//printf("Originisinmiddle!
\nyoucaninput'-'minusn");
printf("请输入起点坐标:
");
scanf("%d%d",&x1,&y1);
printf("请输入终点坐标:
");
scanf("%d%d",&x2,&y2);
printf("请输入画笔颜色:
");
scanf("%d",&color);
initgraph(&gdriver,&gmode,"");
Bresenham_line(0,240,640,240,255);
Bresenham_line(320,0,320,480,255);
Bresenham_line(x1+320,y1+240,x2+320,y2+240,color);
getch();
printf("\ngoon?
:
(y/n)");
c=getch();
if(c=='y'||c=='Y')
gotohere;
}
2.4.2Bresenham画圆
//Bresenham画圆算法
#include"graphics.h"
#include
#include"conio.h"
voidBresenham_Circle(intr,inta,intb,intcolor)
{
intx,y,delta,delta1,delta2,direction;
x=0;
y=r;
delta=2*(1-r);
while(y>=0)
{
putpixel(a+x,b+y,color);
putpixel(a-x,b+y,color);
putpixel(a+x,b-y,color);
putpixel(a-x,b-y,color);
if(delta<0)
{
delta1=2*(delta+y)-1;
if(delta1<=0)direction=1;
elsedirection=2;
}
elseif(delta>0)
{
delta2=2*(delta-x)-1;
if(delta2<=0)direction=2;
elsedirection=3;
}
else
direction=2;
switch(direction)
{
case1:
{
x++;
delta+=2*x+1;
break;
}
case2:
{
x++;
y--;
delta+=2*(x-y+1);
break;
}
case3:
{
y--;
delta+=(-2*y+1);
break;
}
default:
break;
}
}
}
voidBoundaryFill4(intx,inty,intboundarycolor,intnewcolor)
{
intcolor;
color=getpixel(x,y);
if(color!
=newcolor&&color!
=boundarycolor)
{
putpixel(x,y,newcolor);
BoundaryFill4(x,y+1,boundarycolor,newcolor);
BoundaryFill4(x,y-1,boundarycolor,newcolor);
BoundaryFill4(x-1,y,boundarycolor,newcolor);
BoundaryFill4(x+1,y,boundarycolor,newcolor);
}
}
voidmain()
{
intr,color,a,b,ncolor;
intgdriver=DETECT,gmode;
charm[100]={0};
printf("请输入圆的半径r:
");
scanf("%d",&r);
printf("请输入圆心坐标:
");
scanf("%d%d",&a,&b);
printf("请输入边界颜色和填充颜色:
");
scanf("%d%d",&color,&ncolor);
initgraph(&gdriver,&gmode,"D:
\\TC");
Bresenham_Circle(r,a,b,color);
BoundaryFill4(a,b,color,ncolor);
sprintf(m,"(%d,%d)",a,b);
outtextxy(a,b,m);
getch();
closegraph();
}
2.5运行结果图
图2.5.1Bresenham画线算法当k>1时运行结果截图
图2.5.2Bresenham画线算法当k>1时运行结果截图
图2.5.3Bresenham画线算法当1>k>0时运行结果截图
图2.5.4Bresenham画线算法当1>k>0时运行结果截图
图2.5.5Bresenham画线算法当k<-1时运行结果截图
图2.5.6Bresenham画线算法当k<-1时运行结果截图
图2.5.7Bresenham画线算法当-1图2.5.8Bresenham画线算法当-1Bresenham画圆:
图2.5.9Bresenham画圆算法运行结果截图
图2.5.10Bresenham画圆算法运行结果截图
:
实验题三
3.1实验题目
自学椭圆的Bresenham生成算法,利用对称性将该算法程序推广到任一四分圆,从而形成一般的Bresenham画椭圆算法。
并上机编程画出一个圆心在点(xc,yc);沿x轴方向的长半轴长度为a,沿y轴方向的短半轴