图形学实验报告.docx
《图形学实验报告.docx》由会员分享,可在线阅读,更多相关《图形学实验报告.docx(30页珍藏版)》请在冰点文库上搜索。
图形学实验报告
计算机图形学实验报告
1、直线的生成程序设计:
实验目的:
掌握直线段的生成算法,并用C/WIN-TC/VC++实现算法,包括中点法生成直线,微分数值法生成直线段等。
实验内容:
用不同的方法生成斜率不同的直线段,比较各种方法的效果。
/////////////////////////////////////////////////////////////////////////////
//CLineViewdrawing
voidDDALine(intx1,inty1,intx2,inty2,intcolor,CDC*pDC)//数值微分法
{
intx;
intk,y=y1;
k=1.0*(y2-y1)/(x2-x1);
for(x=x1;x<=x2;x++)
{
pDC->SetPixel(x,(int)(y+0.5),color);
y=y+k;
}
}
voidMPLine(intx1,inty1,intx2,inty2,intcolor,CDC*pDC)//中点画线法
{
intx,y,a,b,d,d1,d2;
a=y1-y2;b=x2-x1;
y=y1;
d=2*a+b;d1=2*a;d2=2*(a+b);
pDC->SetPixel(x,y,color);
for(x=x1;x<=x2;x++)
{
if(d<0){y++;d+=d2;}
else{d+=d1;}
pDC->SetPixel(x,y,color);
}
}
voidBHLine(intx1,inty1,intx2,inty2,intcolor,CDC*pDC)//Bresenham画线法
{
intx,y,dx,dy,dk;
dx=abs(x2-x1);dy=abs(y2-y1);
dk=2*dy-dx;y=y1;
for(x=x1;x<=x2;x++)
{
pDC->SetPixel(x,y,color);
dk=dk+2*dy;
if(dk>=0)
{y++;dk=dk-2*dx;}
}
}
voidCLineView:
:
OnDraw(CDC*pDC)
{
CLineDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
DDALine(100,100,200,70,255,pDC);//数值微分法
pDC->TextOut(200,70,"数值微分画线");
MPLine(100,120,200,140,255,pDC);//中点画线法
pDC->TextOut(200,140,"中点画线");
BHLine(100,140,200,190,255,pDC);//Bresenham画线法
pDC->TextOut(200,190,"Bresenham画线法");
//TODO:
adddrawcodefornativedatahere
}
运行结果:
2、圆的生成程序设计:
实验目的:
掌握用C/WIN-TC/VC++实现算法,圆的生成算法
实验内容:
用中点画圆法、Bresenham画圆法
/////////////////////////////////////////////////////////////////////////////
//CCircleViewdrawing
voidWholeCircle(intxc,intyc,intx,inty,intcolor,CDC*pDC)
{
pDC->SetPixel(xc+x,yc+y,color);
pDC->SetPixel(xc-x,yc+y,color);
pDC->SetPixel(xc+x,yc-y,color);
pDC->SetPixel(xc-x,yc-y,color);
pDC->SetPixel(xc+y,yc+x,color);
pDC->SetPixel(xc-y,yc+x,color);
pDC->SetPixel(xc+y,yc-x,color);
pDC->SetPixel(xc-y,yc-x,color);
}
voidMidCircle(intxc,intyc,intr,intcolor,CDC*pDC)//中点画圆法
{
intx,y,d;
x=0;y=r;d=1-r;
WholeCircle(xc,yc,x,y,color,pDC);
while(x<=y)
{
if(d<0)
{d+=2*x+3;x++;}
else
{d+=2*(x-y)+5;x++;y--;}
WholeCircle(xc,yc,x,y,color,pDC);
}
WholeCircle(xc,yc,x,y,color,pDC);
}
voidBresenhamCircle(intxc,intyc,intr,intcolor,CDC*pDC)//Bresenham画圆法
{intx,y,d;
x=0;y=r;
d=3-2*r;
while(x{
WholeCircle(xc,yc,x,y,color,pDC);
if(d<0)
d=d+4*x+6;
else
{
d=d+4*(x-y)+10;
y--;
}
x++;
}
if(x==y)WholeCircle(xc,yc,x,y,color,pDC);
}
voidCCircleView:
:
OnDraw(CDC*pDC)
{
CCircleDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
MidCircle(100,100,70,255,pDC);//中点画圆法
pDC->TextOut(175,100,"中点画圆法");
BresenhamCircle(100,250,80,255,pDC);//Bresenham画圆法
pDC->TextOut(185,250,"Bresenham画圆法");
//TODO:
adddrawcodefornativedatahere
}
运行结果:
3、椭圆的生成程序设计:
实验目的:
掌握用C/WIN-TC/VC++实现算法,椭圆的生成算法
实验内容:
实现椭圆的算法
//CMPEllipseViewdrawing
voidWholeEllipse(intxc,intyc,intx,inty,intcolor,CDC*pDC)
{
pDC->SetPixel(xc+x,yc+y,color);
pDC->SetPixel(xc+x,yc-y,color);
pDC->SetPixel(xc-x,yc+y,color);
pDC->SetPixel(xc-x,yc-y,color);
}
voidMidEllipse(intxc,intyc,inta,intb,intcolor,CDC*pDC)
{
intaa=a*a,bb=b*b;
inttwoaa=2*aa,twobb=2*bb;
intx=0,y=b;
intdx=0,dy=twoaa*y;
intd=(int)(bb+aa*(-b+0.25)+0.5);
WholeEllipse(xc,yc,x,y,color,pDC);
while(dx{
x++;dx+=twobb;
if(d<0)
d+=bb+dx;
else
{y--;dy-=twoaa;d+=bb+dx-dy;}
WholeEllipse(xc,yc,x,y,color,pDC);
}
d=(int)(bb*(x+0.5)*(x+0.5)+aa*(y-1)*(y-1)-aa*bb+0.5);
while(y>0)
{
y--;dy-=twoaa;
if(d>0)
d+=aa-dy;
else
{x++;dx+=twobb;d+=aa-dy+dx;}
WholeEllipse(xc,yc,x,y,color,pDC);
}
}
voidCMPEllipseView:
:
OnDraw(CDC*pDC)
{
CMPEllipseDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
MidEllipse(200,100,100,50,255,pDC);
pDC->TextOut(305,100,"中点画椭圆法");
//TODO:
adddrawcodefornativedatahere
}
运行结果:
4.有序边表填充算法程序设计
实验目的:
掌握用C/WIN-TC/VC++实现算法,有序边生成算法
实验内容:
实现有序边填充算法
代码如下:
#defineWINDOW_HEIGHT480
#defineNULL0
typedefstructtEdge/*有序便表和活化边表的结构*/
{
intymax;
floatx,dx;
structtEdge*next;
}Edge;
typedefstructpoint
{
intx,y;
}tPOINT;
voidInsertEdge(Edge*list,Edge*edge)
{
Edge*p,*q=list;
p=q->next;
while(p)
{
if(edge->xx)
{
p=NULL;
}
else
{
q=p;
p=p->next;
}
}
edge->next=q->next;
q->next=edge;
}
intyNext(intk,intcnt,tPOINT*pts)
{
intj;
if((k+1)>(cnt-1))
{
j=0;
}
else
{
j=k+1;
}
while(pts[k].y==pts[j].y)
{if((j+1)>(cnt-1))
{j=0;
}
else
{j++;
}
}
returnpts[j].y;
}
voidMakeEdgeRec(tPOINTlower,tPOINTupper,intyComp,Edge*edge,Edge*edges[])/*生成有序边表的一条边*/
{
edge->dx=(float)(upper.x-lower.x)/(upper.y-lower.y);
edge->x=lower.x;
if(upper.y{
edge->ymax=upper.y-1;
}
else
{
edge->ymax=upper.y;
}
InsertEdge(edges[lower.y],edge);
}
voidBuildEdgeList(intcnt,tPOINT*pts,Edge*edges[])
{Edge*edge;
tPOINTv1,v2;
inti,yPrev=pts[cnt-2].y;
v1.x=pts[cnt-1].x;
v1.y=pts[cnt-1].y;
for(i=0;i{
v2=pts[i];
if(v1.y!
=v2.y)
{
edge=(Edge*)malloc(sizeof(Edge));/*C语言中的malloc*/
if(v1.y{
MakeEdgeRec(v1,v2,yNext(i,cnt,pts),edge,edges);
}
else
{
MakeEdgeRec(v2,v1,yPrev,edge,edges);
}
yPrev=v1.y;
v1=v2;
}
}
}
voidBuildActiveList(intscan,Edge*active,Edge*edges[])
{
Edge*p,*q;
p=edges[scan]->next;
while(p)
{
q=p->next;
InsertEdge(active,p);
p=q;
}
}
voidFillScan(intscan,Edge*active,intcolor,CDC*pDC)
{
inti;
Edge*p1,*p2;
p1=active->next;
while(p1)
{
p2=p1->next;
for(i=p1->x;ix;i++)
{
pDC->SetPixel((int)i,scan,color);
}
p1=p2->next;
}
}
voidDeletAfter(Edge*q)
{
Edge*p=q->next;
q->next=p->next;
free(p);
}
voidUpdateActiveList(intscan,Edge*active)
{
Edge*q=active,*p=active->next;
while(p)
{
if(scan>=p->ymax)
{
p=p->next;
DeletAfter(q);
}
else
{
p->x=p->x+p->dx;
q=p;
p=p->next;
}
}
}
voidResortActiveList(Edge*active)
{
Edge*q,*p=active->next;
active->next=NULL;
while(p)
{
q=p->next;
InsertEdge(active,p);
p=q;
}
}
voidScanFill(intcnt,tPOINT*pts,intcolor,CDC*pDC)
{
Edge*edges[WINDOW_HEIGHT],*active;
inti,scan,scanmax=0,scanmin=WINDOW_HEIGHT;
for(i=0;i{
if(scanmax{
scanmax=pts[i].y;
}
if(scanmin>pts[i].y)
{
scanmin=pts[i].y;
}
}
for(scan=scanmin;scan<=scanmax;scan++)
{
edges[scan]=(Edge*)malloc(sizeof(Edge));
edges[scan]->next=NULL;
}
BuildEdgeList(cnt,pts,edges);
active=(Edge*)malloc(sizeof(Edge));
active->next=NULL;
for(scan=scanmin;scan<=scanmax;scan++)
{
BuildActiveList(scan,active,edges);
if(active->next)
{
FillScan(scan,active,color,pDC);
UpdateActiveList(scan,active);
ResortActiveList(active);
}
}
}
CFillView:
:
CFillView()
{
//TODO:
addconstructioncodehere
}
CFillView:
:
~CFillView()
{
}
BOOLCFillView:
:
PreCreateWindow(CREATESTRUCT&cs)
{
//TODO:
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
:
PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
//CFillViewdrawing
voidCFillView:
:
OnDraw(CDC*pDC)
{
CFillDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
tPOINTpoints[3]={{100,80},{300,100},{300,260}};
tPOINT*p=points;
intcolor=RGB(255,2,0);
ScanFill(3,p,color,pDC);
}
运行结果:
8.Cohen-SutherLand编码裁剪算法程序设计
#defineLEFT1
#defineRIGHT2
#defineBOTTOM4
#defineTOP8
typedefstructpoint{intx,y;}POINT1;
voidEncode(intx,inty,int*code,intXL,intXR,intYB,intYT,CDC*pDC)
{
intc=0;
if(xelseif(x>XR)c=c|RIGHT;
if(yelseif(y>YT)c=c|TOP;
(*code)=c;
}
voidC_S_Line(POINTp1,POINTp2,intXL,intXR,intYB,intYT,CDC*pDC)
{
intx1,x2,y1,y2,x,y;
intcode1,code2,code;
x1=p1.x;x2=p2.x;y1=p1.y;y2=p2.y;
Encode(x1,y1,&code1,XL,XR,YB,YT,pDC);
Encode(x2,y2,&code2,XL,XR,YB,YT,pDC);
while(code1!
=0||code2!
=0)
{
if((code1&code2)!
=0)return;
code=code1;
if(code1==0)code=code2;
if((LEFT&code)!
=0)
{
x=XL;
y=y1+(y2-y1)*(XL-x1)/(x2-x1);
}
elseif((RIGHT&code)!
=0)
{
x=XR;
y=y1+(y2-y1)*(XR-x1)/(x2-x1);
}
elseif((BOTTOM&code)!
=0)
{
y=YB;
x=x1+(x2-x1)*(YB-y1)/(y2-y1);
}
elseif((TOP&code)!
=0)
{
y=YT;
x=x1+(x2-x1)*(YT-y1)/(y2-y1);
}
if(code==code1)
{
x1=x;y1=y;
Encode(x,y,&code1,XL,XR,YB,YT,pDC);
}
else
{
x2=x;y2=y;
Encode(x,y,&code2,XL,XR,YB,YT,pDC);
}
}
p1.x=x1;p1.y=y1;p2.x=x2;p2.y=y2;
pDC->MoveTo(p1.x,p1.y);
pDC->LineTo(p2.x,p2.y);
}
voidCCohenView:
:
OnDraw(CDC*pDC)
{
CCohenDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
POINTp1,p2,p3,p4,p5,p6,p7,p8;
p1.x=35;p1.y=160;
p2.x=245;p2.y=121;
p3.x=120;p3.y=60;
p4.x=200;p4.y=300;
p5.x=169;p5.y=45;
p6.x=150;p6.y=200;
p7.x=120;p7.y=200;
p8.x=220;p8.y=130;
pDC->LineTo(120,100);
pDC->LineTo(210,100);
pDC->LineTo(220,180);
pDC->LineTo(120,170);
pDC->LineTo(110,100);
C_S_Line(p1,p2,100,200,90,170,pDC);
C_S_Line(p3,p4,100,200,90,170,pDC);
}
运行结果:
6.基于链队列的种子填充算法程序设计
程序代码:
#defineNULL0
typedefstructpoint{intx,y;}POINT1;
typedefstructQNode
{
POINTData;
structQNode*Next;
}QNode,*QPtr;
typedefstruct
{
QPtrFront;
QPtrRear;
}LinkQueue;
LinkQueueq;
voidCreateQueue()
{
q.Front=q.Rear=(QPtr)malloc(sizeof(QNode));
q.Rear->Next=NULL;
}
POINTDequeue()
{
QNode*p;POINTx;
p=q.Front;x=q.Front->Data;q.Front=q.Front->Next;free(p);
returnx;
}
voidEnqueue(POINTx)
{
QNode*p=(QPtr)mall