搜档网
当前位置:搜档网 › 计算机图形学实验报告实验2裁剪算法实验

计算机图形学实验报告实验2裁剪算法实验

一、实验目的:

直线段的裁剪:编码裁剪算法,中点分割裁剪算法。

二、实验内容:

//BasicGraph.cpp

//请将下列裁剪程序补充完整,并用注释说明是何种裁剪算法

void Encode (int x,int y,int *code,int XL,int XR,int YB,int YT) {

//请将此程序补充完整

int c=0;

if(x

else if(x>XR) c=c|RIGHT;

if(y

else if(y>YT) c=c|TOP;

(*code)=c;

}

//编码裁剪算法:

void C_S_Line(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) {

//请将此程序补充完整

int x1,x2,y1,y2,x,y,code1,code2,code;

x1=p1.x; x2=p2.x; y1=p1.y; y2=p2.y;

Encode(x1,y1,&code1,XL,XR,YB,YT);

Encode(x2,y2,&code2,XL,XR,YB,YT);

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);}

else if((RIGHT&code)!=0)

{x=XR;y=y1+(y2-y1)*(XR-x1)/(x2-x1);}

if((BOTTOM&code)!=0)

{y=YB;x=x1+(x2-x1)*(YB-y1)/(y2-y1);}

else if((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);}

else

{x2=x;y2=y;Encode(x,y,&code2,XL,XR,YB,YT);}

}

p1.x=x1;p1.y=y1;p2.x=x2;p2.y=y2;

}

int IsInArea(POINT point,int XL,int XR,int YB,int YT)

{

//请将此程序补充完整

if(point.x>=XL && point.x<=XR && point.y>YB && point.y

else return 0;

}

int NotIntersect(POINT begin,POINT end,int XL,int XR,int YB,int YT) {

//请将此程序补充完整

int maxx,maxy,minx,miny;

maxx=(begin.x>end.x)?begin.x:end.x;

minx=(begin.x

maxy=(begin.y>end.y)?begin.y:end.y;

miny=(begin.y

if(maxxXR||maxyYT) return 1;

else return 0;

}

//中点裁剪算法:

POINT ClipMid(POINT begin,POINT end,int XL,int XR,int YB,int YT)

{

//请将此程序补充完整

POINT mid,temp;

if(IsInArea(begin,XL,XR,YB,YT)) temp=begin;

else if(NotIntersect(begin,end,XL,XR,YB,YT)) temp=begin;

else

{

mid.x=(begin.x+end.x)/2;mid.y=(begin.y+end.y)/2;

if(abs(mid.x-end.x)<=1&& abs(mid.y-end.y)<=1) temp=mid;

else

{

if(NotIntersect(begin,mid,XL,XR,YB,YT))

temp=ClipMid(mid,end,XL,XR,YB,YT);

else

temp=ClipMid(begin,mid,XL,XR,YB,YT);

}

}

return temp;

}

//Liang-Barsky直线裁剪算法:

void ClipParameter(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) {

float u1=0.0,u2=1.0;

float dx=p2.x-p1.x,dy=p2.y-p1.y;

if(clipTest(-dx,p1.x-XL,&u1,&u2))

if(clipTest(dx,XR-p1.x,&u1,&u2))

if(clipTest(-dy,p1.y-YB,&u1,&u2))

if(clipTest(dy,YT-p1.y,&u1,&u2))

{

if(u2<1.0)

{

p2.x=p1.x+u2*dx;

p2.y=p1.y+u2*dy;

}

if(u1>0.0)

{

p1.x=p1.x+u1*dx;

p1.y=p1.y+u1*dy;

}

}

}

int clipTest(float p,float q,float *u1,float *u2)

{

float r;

int remainFlag=1;

if(p<0.0)

{

r=q/p;

if(r>*u2) remainFlag=0;

else if(r>*u1) *u1=r;

}

else if(p>0.0)

{

r=q/p;

if(r<*u1) remainFlag=0;

else if(r<*u2) *u2=r;

}

else //*p=0

if(q<0.0) remainFlag=0;

return remainFlag;

}

//逐边裁剪算法:

//typedef struct tRes { int yes,isIn; POINT pout;} Res;

Res TestIntersect(int edge,int type,POINT p1,POINT p2)

{//判断p2是否在所裁剪的窗边edge的内侧,是否与p1点分别在窗边edge的异侧

float dx,dy,m;

Res res;int isIn=0,yes=0;POINT pout;

dy=p2.y-p1.y;dx=p2.x-p1.x;m=dy/dx;

switch(type)

{

case 1: /*right*/

if(p2.x<=edge){isIn=1;if(p1.x>edge)yes=1;}

else if(p1.x<=edge)yes=1;break;

case 2: /*bottom*/

if(p2.y>=edge){isIn=1;if(p1.y

else if(p1.y>=edge)yes=1;break;

case 3: /*left*/

if(p2.x>=edge){isIn=1;if(p1.x

else if(p1.x>=edge)yes=1;break;

case 4: /*top*/

if(p2.y<=edge){isIn=1;if(p1.y>edge)yes=1;}

else if(p1.y<=edge)yes=1;

default: break;

}

if(yes)

{

if((type==1) || (type==3))

{ pout.x=edge;pout.y=p1.y+m*(pout.x-p1.x);}

if((type==2) || (type==4))

{ pout.y=edge;pout.x=p1.x+(pout.y-p1.y)/m;}

}

res.isIn=isIn;res.yes=yes;res.pout=pout;

return res;

}

int clipSingleEdge(int edge,int type,int nin,POINT pin[50],POINT pout[50])

/*对多边形pin与窗边edge进行裁剪,返回裁剪后的多边形pout及点数*/ {

int i,k=0;POINT p;Res res;

p.x=pin[nin-1].x;p.y=pin[nin-1].y;

for(i=0;i

{

res=TestIntersect(edge,type,p,pin[i]);

if(res.yes)

{ pout[k].x=res.pout.x;pout[k].y=res.pout.y;k++;} if(res.isIn)

{ pout[k].x=pin[i].x;pout[k].y=pin[i].y;k++;}

p.x=pin[i].x;p.y=pin[i].y;

}

return k;

}

void ClipEdgePolygon(POINT ps[50],int &n,int XL,int XR,int YB,int YT) { /*对多边形ps进行逐边裁剪*/

int n1=0,n2=0;

POINT pt[50];

n1=clipSingleEdge(XR,1,n,ps,pt);

n2=clipSingleEdge(YB,2,n1,pt,ps);

n1=clipSingleEdge(XL,3,n2,ps,pt);

n2=clipSingleEdge(YT,4,n1,pt,ps);

n=n2;

}

//多边形编码裁剪算法:

void ClipEncodePolygon(POINT ps[50],int &n,int XL,int XR,int YB,int YT) {

POINT tp[50];

int k=0,m;

int code1,code2,code;

int x,y;

for(int i=0;i

{

Encode(ps[i].x,ps[i].y,&code1,XL,XR,YB,YT);

Encode(ps[i+1].x,ps[i+1].y,&code2,XL,XR,YB,YT);

code=code1;m=i;

for(int j=0;j<2;j++)

{

if((code1 & code2)!=0) //线段两端都在窗口外的同一侧

{

switch(code)

{

case 1:x=XL;y=ps[m].y;break;

case 2:x=XR;y=ps[m].y;break;

case 4:x=ps[m].x;y=YB;break;

case 5:x=XL;y=YB;break;

case 6:x=XR;y=YB;break;

case 8:x=ps[m].x;y=YT;break;

case 9:x=XL;y=YT;break;

case 10:x=XR;y=YT;break;

}

tp[k].x=x;tp[k].y=y;k++;

}

else if((code1 & code2)==0) //线段两端不在窗口的同一侧

{

if(code==0)

{

tp[k]=ps[m];k++;

}

else if ((LEFT & code) !=0) //线段与左边界相交 {

x=XL;

y=ps[i].y+(ps[i+1].y-ps[i].y)*(XL-ps[i].x)/(ps[i+1].x-ps[i].x);

if(y>YB && y

}

else if((TOP & code)!=0) //线段与上边界相交

{

y=YT;

x=ps[i].x+(ps[i+1].x-ps[i].x)*(YT-ps[i].y)/(ps[i+1].y-ps[i].y);

if(x>XL && x

}

else if((RIGHT & code)!=0) //线段与右边界相交 {

x=XR;

y=ps[i].y+(ps[i+1].y-ps[i].y)*(XR-ps[i].x)/(ps[i+1].x-ps[i].x);

if(y>YB && y

}

else if((BOTTOM & code) != 0) //线段与下边界相交 {

y=YB;

x=ps[i].x+(ps[i+1].x-ps[i].x)*(YB-ps[i].y)/(ps[i+1].y-ps[i].y);

if(x>XL && x

}

}

code=code2;m++;

}//for(j)

}//for(i)

for(i=0;i

ps[i]=tp[i];

n=k;

}

//函数的调用,裁剪窗口的调整

//DrawView.cpp文件

//裁剪窗口的调整

CDrawView::CDrawView()

{

/************请在此函数中将裁剪窗口大小调整为长度100单位像素,宽度50单位像素的矩形********/

// TODO: add construction code here

//

m_pWidth=1;

m_pStyle=PEN_STYLE_SOLID;

m_pColor=RGB(0,0,0);

m_FFlag=0;

m_FColor=RGB(0,0,0);

m_HFlag=0;

CurrentDraw=DRAW_VCLINE;

m_Num=0;

m_Drag=0;

m_HCursor=AfxGetApp()->LoadStandardCursor(IDC_CROSS);

//

DrawType=0;

ClipFlag=0;

ClipType=-1;

XL=200;XR=300;YB=150;YT=200;

//XL=200;XR=500;YB=150;YT=400;

ClipWindowColor=RGB(192,192,50);

}

void CDrawView::OnDraw(CDC* pDC)

{

CDrawDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

if(ClipFlag)

{

CPen NewPen,*pOldPen;

NewPen.CreatePen(PS_DASH,1,ClipWindowColor);

pOldPen=pDC->SelectObject(&NewPen);

pDC->MoveTo(XL,YB);

pDC->LineTo(XR,YB);

pDC->LineTo(XR,YT);

pDC->LineTo(XL,YT);

pDC->LineTo(XL,YB);

}

int index;

index=pDoc->GetShapeNumber();

for(int i=0;i

pDoc->GetShape(i)->Drawing(pDC);

}

void CDrawView::OnInitialUpdate()

{

CSize sizeTotal;

sizeTotal.cx = 640; sizeTotal.cy = 480;

SetScrollSizes(MM_TEXT, sizeTotal);

// TODO: Add your specialized code here and/or call the base class }

void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CClientDC dc(this);

OnPrepareDC(&dc);

dc.DPtoLP(&point);

m_pPrev=point;

m_pOrigin=point; //点击鼠标左键作为拖动绘图的第一点

m_Drag=1;

SetCapture();

RECT rect;

GetClientRect(&rect);

ClientToScreen(&rect);

ClipCursor(&rect);

CScrollView::OnLButtonDown(nFlags, point);

}

//函数调用处

void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

if(m_Drag)

{

m_Drag=0;

ReleaseCapture();

ClipCursor(NULL);

CDrawDoc *pDoc=GetDocument();

CShape *pShape;

POINT p1,p2;

if(CurrentDraw==DRAW_VCLINE || CurrentDraw==DRAW_DDALINE ||

CurrentDraw==DRAW_MIDLINE || CurrentDraw==DRAW_BSHLINE)

{

if(ClipFlag)

{

switch(ClipType)

{

/****************编码裁剪函数调用处*************/

case CLIP_ENCODE:C_S_Line(m_pOrigin,m_pPrev,XL,XR,YB,YT); break; /****************中点分割裁剪函数调用处************/

case CLIP_MIDPOINT: ClipMid(m_pPrev,m_pOrigin,XL,XR,YB,YT);

p1=ClipMid(m_pPrev,m_pOrigin,XL,XR,YB,YT);

p2=ClipMid(m_pOrigin,m_pPrev,XL,XR,YB,YT);

m_pOrigin=p1;m_pPrev=p2;

break;

case CLIP_PARAMETER:ClipParameter(m_pOrigin,m_pPrev,XL,XR,YB,YT);

break;

}

}

pShape=new

CLine(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,DrawType);

pDoc->AddShape(pShape);

}

if(CurrentDraw==DRAW_RECTANGLE)

{

if(ClipType==CLIP_WINDOW)

{

XL=m_pOrigin.x;XR=m_pPrev.x;

YB=m_pOrigin.y;YT=m_pPrev.y;

}

else

{

pShape=new

CRectangle(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,

m_FFlag,m_FColor,m_HFlag,m_Hatch);

pDoc->AddShape(pShape);

}

}

if( CurrentDraw==DRAW_VCCIRCLE || CurrentDraw==DRAW_MIDCIRCLE || CurrentDraw==DRAW_BSHCIRCLE)

{

pShape=new

CCircle(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,

m_FFlag,m_FColor,m_HFlag,m_Hatch,DrawType);

pDoc->AddShape(pShape);

}

if(CurrentDraw==DRAW_VCELLIPSE || CurrentDraw==DRAW_MIDELLIPSE) {

pShape=new

CEllipse(m_pOrigin,m_pPrev,m_pWidth,m_pStyle,m_pColor,

m_FFlag,m_FColor,m_HFlag,m_Hatch,DrawType);

pDoc->AddShape(pShape);

}

pDoc->UpdateAllViews(NULL);

}

CScrollView::OnLButtonUp(nFlags, point);

}

三实验结果:

四、实验总结

通过这次试验使我了解到如何运用计算机程序对窗口进行剪裁,了解到编码剪裁算法直观方便,速度较快,中点分割剪裁算法不用进行乘除运算,剪裁效率高,Liang-Barsky直线裁剪算法更快。

计算机图形学实验指导书(vc++版)

实验指导书 刘文涛 2013

目录 第一章图形学实验环境和要求 (4) 1.1 VC++实验环境 (4) 1.1.1 基本环境 (4) 1.1.1 开发图形程序的一般流程 (7) 1.1.3 基本绘图函数介绍 (11) 1.2 OpenGL (22) 1.2.1 OpenGL介绍 (22) 1.2.2 OpenGL开发环境 (24) 1.2.3 OpenGL函数 (24) 1.2.4 回调函数 (25) 1.2.4 一个典型OpenGL例程 (26) 1.3 实验要求 (29) 1.3.1 实验内容 (29) 1.3.2 实验方法 (29) 1.3.3 实验效果 (30) 第二章直线生成算法 (30) 2.1 实验原理 (30) 2.1.1 DDA算法 (30) 2.1.2 Bresenham算法 (30) 2.2 实验内容 (30) 2.3 参考示例程序 (30) 第三章圆和椭圆生成算法 (32) 3.1 实验原理 (32) 3.2 实验内容 (32) 3.3 参考示例程序1 (32) 3.4 参考示例程序2 (33) 第四章裁剪算法 (35) 4.1 实验原理 (35) 4.2 实验内容 (35) 4.3 示例程序 (35) 4.3.1 参考例子1 (35) 4.3.2参考例子2 (38) 第五章二维变换 (40) 5.1 实验原理 (40) 5.2 实验内容 (40) 5.3 示例程序 (40) 5.3.1参考例子1 (40) 第六章三维变换 (44)

6.1 实验原理: (44) 6.2 实验内容 (45) 6.3示例程序 (45) 第七章填充算法 (47) 7.1 实验原理: (47) 7.2 实验内容 (47) 7.3示例程序 (47) 第八章曲线曲面 (50) 8.1 实验原理 (50) 8.2 实验内容 (50) 8.3示例程序 (51) 8.3.1 参考例子(1) (51) 8.3.2 参考例子(2) (52) 8.3.3 参考例子(3) (54) 8.3.4 参考例子(4) (56) 第九章真实感图形绘制 (59) 9.1 实验原理 (59) 9.2 实验内容 (59) 9.3示例程序 (59) 9.3.1参考例子(1) (59) 9.3.2参考例子(2) (61) 9.3.3参考例子(3) (63) 第十章动画 (66) 10.1 实验原理 (66) 10.2 实验内容 (66) 10.3示例程序 (66) 10.3.1 参考例子 (66) 参考文献: (72)

计算机图形学实验报告

计算机图形学 实验报告 学号: 姓名: 班级:计算机 2班 指导老师:何太军 2010.6.19

实验一、Windows 图形程序设计基础 1、实验目的 1)学习理解Win32 应用程序设计的基本知识(SDK 编程); 2)掌握Win32 应用程序的基本结构(消息循环与消息处理等); 3)学习使用VC++编写Win32 Application 的方法。 4)学习MFC 类库的概念与结构; 5)学习使用VC++编写Win32 应用的方法(单文档、多文档、对话框); 6)学习使用MFC 的图形编程。 2、实验内容 1)使用WindowsAPI 编写一个简单的Win32 程序,调用绘图API 函数绘制若干图形。(可选任务) 2 )使用MFC AppWizard 建立一个SDI 程序,窗口内显示"Hello,This is my first SDI Application"。(必选任务) 3)利用MFC AppWizard(exe)建立一个SDI 程序,在文档视口内绘制基本图形(直线、圆、椭圆、矩形、多边形、曲线、圆弧、椭圆弧、填充、文字等),练习图形属性的编程(修改线型、线宽、颜色、填充样式、文字样式等)。定义图形数据结构Point\Line\Circle 等保存一些简单图形数据(在文档类中),并在视图类OnDraw 中绘制。 3、实验过程

1)使用MFC AppWizard(exe)建立一个SDI 程序,选择单文档; 2)在View类的OnDraw()函数中添加图形绘制代码,说出字符串“Hello,This is my first SDI Application”,另外实现各种颜色、各种边框的线、圆、方形、多边形以及圆弧的绘制; 3)在类视图中添加图形数据point_pp,pp_circle的类,保存简单图形数据,通过在OnDraw()函数中调用,实现线、圆的绘制。 4、实验结果 正确地在指定位置显示了"Hello,This is my first SDI Application"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。成功地完成了实验。 结果截图: 5、实验体会 通过实验一,了解了如用使用基本的SDI编程函数绘制简单的图

多边形裁剪地Sutherland—Hodgman算法(计算机图形学)

多边形裁剪的Sutherland—Hodgman算法 1>. Sutherland—Hodgman多边形裁剪算法思想 该算法的基本思想是每次用窗口的一条边界及其延长线来裁剪多边形的各边。多边形通常由它的顶点序列来表示,经过裁剪规则针对某条边界裁剪后,结果形成新的顶点序列,又留待下条边界进行裁剪,…,直到窗口的所有边界都裁剪完毕,算法形成最后的顶点序列,才是结果多边形(它可能构成一个或多个多边形)。当多边形一个顶点Pi相对于窗口某条边界及其延长线进行剪裁时,不外乎下列四种情况(即裁剪规则): 1、顶点Pi在内侧,前一顶点Pi-1也在内侧,则将Pi纳入新的顶点序列; 2、顶点Pi在内侧,前一顶点Pi-1在外侧,则先求交点Q,再将Q、Pi依次纳入新的顶点序列; 3、顶点Pi在外侧,前一顶点Pi-1在内侧,则先求交点Q,再将Q纳入新的顶点序列; 4、顶点Pi与前一顶点Pi-1均在外侧,则顶点序列中不增加新的顶点。 2>. Sutherland—Hodgman多边形裁剪算法步骤 考虑多边形相对于一条边界及其延长线进行裁剪的算法: 1.从主函数得到待裁剪多边形的顶点序列P[][2]、顶点序列数n、窗口一条边界参数xl(假如为矩形窗口的左边界); 2.赋初值:将顶点序列中的最后一个顶点赋给前一顶点S; 设置初始标志flag: if(S在边界内侧)flag=0; else flag=1; 设新的顶点序列数j=0; 3.对多边形各顶点进行裁剪规则处理,结果放入新的多边形顶点序列Q[][2]中:for(对第一个顶点直到最后一个顶点,逐一处理) { if(Pi在边界内侧) { if(flag!=0) { flag=0; 求交点并放入新的多边形顶点序列Qj中; j++; } 将当前顶点放入新的多边形顶点序列Qj中:Qj=Pi; j++; } else { if(flag==0) { flag=1; 求交点并放入新的多边形顶点序列Qj中; j++;

《计算机图形学》实验报告

实验报告模板 《计算机图形学》实验报告 一、实验目的及要求 1.实习三维图形的坐标系之间的变换; 2.三维图形几何变换; 3.掌握三维图形的坐标系之间的变换算法及三维图形几何变换的原理和实现;4.实现二维图形的基本变换(平移、旋转、缩放、错切、对称、复合等);5.实现三维图形的基本变换(平移、旋转、缩放、复合等); 二、理论基础 在齐次坐标理论下,二维图形几何变换矩阵可用下式表示: ? ? ? ? ? ? ? = = = i f c h e b g d a T n k x x k k 2,1,0 , ) ( ? 平移变换:[x* y* 1] =[x y 1] * 00 00 001 t s ?? ? ? ? ??=[t*x s*y 1] 比例变换:[x* y* 1]=[x y 1] * 100 010 1 m n ?? ? ? ? ??=[m+x n+y 1] 旋转变换:在平面上的二维图形饶原点逆时针旋转?角,变换矩阵为 [x* y* 1]=[x y 1] * cos sin0 sin cos0 001 θθ θθ ?? ? - ? ? ??= [x*cos?-y*sin?] 复合变换:以上各种变换矩阵都是以原点为参照点,当以任意参照点进行变换的时候,我们就要用到复合变换矩阵。 三维变换类似于二维,在画图时,把三维坐标转换为二维即可。 三、算法设计与分析 二维变换: #define dx 50 #define dy 100 void CCGWithVCView::OnTransScale() //平移(50,100) { // TODO: Add your command handler code here // AfxMessageBox(_T("Please Insert The Move Change Code!")) ; int m[4][2]={{100,50},{50,100},{150,100},{100,50}}; int i; int a[2],b[2];

计算机图形学

一.填空题(共4题,36.0分) 1 计算机中表示带有颜色及形状信息的图和形常用的方法有点阵法 正确答案: 第一空: 参数法 2 光栅系统中的颜色模型主要有RGB、CMY、YIQ和HSV等,其中主要用于彩色光栅图形显 正确答案: 第一空: RGB 第二空: HSV 3 采用C ohen-Sutherland(编码裁剪)算法裁剪直线段,可分为三个步骤: (2)判别线段两个端点是否都落在窗口某一条边所在直线的外侧,如果是,

(3)如果不满足前面的两个条件,则求交点,去掉交点外的线段,对剩余线段重复(1)和 (2)。 切换到文本模式 切换到文本模式 正确答案: 第一空: 完全可见,裁剪结束 第二空: 完全不可见,裁剪结束 4 给定4个控制顶点P0(x0,y0),P1(x1,y1),P2(x2,y2),P3(x3,y3)构造一条均匀周期性二次B样条曲线,则曲线的起点坐标 正确答案: 第一空: (P0+P1)/2;((x0+x1)/2 第二空: (y0+y1)/2 二.综合题(共7题,64.0分)

1 利用中点 Bresenham 画圆算法的原理,按逆时针方向推导第一象限y=0到y=x圆弧段的扫描转换算法(要求写清原理、误差函数、递推公式)。 •填写答案 • 正确答案: 参考解答:起点为(R,0),最大的位移方向是y方向,故每次Y方向上增加1,X方向上可能减1或减0。假设当前点为Pi(xi ,yi ),下一个点可能是Pd(xi -1,yi +1),也可能是Pu(xi ,yi +1),两者的中点为M(xi -0.5,yi +1)。则当F(xm,ym)<0时,M在圆内,说明Pu(xi ,yi +1)离圆弧更近,应取Pu(xi ,yi +1)作为下一像素。F(xm,ym)>0时,M在圆外,说明Pd(xi -1,yi +1)离圆弧更近,应取Pu(xi ,yi +1)作为下一像素。F(xm,ym)=0时,M 在圆上,取Pd(xi -1,yi +1)和Pu(xi ,yi +1)均可,约定取Pd(xi -1,yi +1)。(5分) 判别式为:di=F(xi -0.5,yi +1)= (xi -0.5)2+(yi +1)2-R2 若di>=0,则取P d(xi -1,yi +1),否则若di<0,则取P u(xi,yi +1)。 (1)若di>=0,则取P d(xi -1,yi +1),则下一个中点则是M (xi -1.5,yi +2)。 di+1= F(xi -1.5,yi +2)= (xi -1.5)2+(yi +2)2-R2 = di-2xi+2yi+5 所以当d>=0时,判别式d的增量为-2xi+2yi+5。 (2)若di<0,则取P d(xi,yi +1),则下一个中点则是M (xi -0.5,yi +2)。 di+1= F(xi -0.5,yi +2)= (xi -0.5)2+(yi +2)2-R2 = di+2yi+3 所以当d>=0时,判别式d的增量为 2yi+3。(12分) (3)di的初值计算:所绘制圆弧段的第一个像素是P0(R,0),因此判别式d的初始值为 d0= F(R -0.5,1)= (R -0.5)2+12-R2=1.25-R 因为只是要求出d0的符号,而且R是整数,因此求1.25-R的符号等价于求1-R的符号。因此取d0=1-R。(15分) 2

计算机图形学实验报告及代码

计算机图形学实验报告及代码 第 1 章概述 一、教学目标 通过本章的学习,使学生能够了解计算机图形学的基本概念、研究内容;当前的发展概况;本门课程的特点和应用。 二、教学要求 1.了解计算机图形学的概念和研究内容; 2.了解本门课程的发展概况。 三、教学内容提要 1. 计算机图形学的研究内容 2. 计算机图形学发展概况 3. 计算机图形学特点和应用 4. 计算机图形学当前研究的课题 5. 计算机图形生成和输出的流水线 四、教学重点、难点及解决方法 本章将主要围绕计算机图形学的基本概念进行介绍,介绍研究内容;当前的发展概况;本门课程的特点和应用等等。 五、课时安排 2学时 六、教学设备 多媒体 七、检测教学目标实现程度的具体措施和要求 通过课堂提问的方式来检测学生对基本概念的掌握程度。 八、教学内容 1.1 计算机图形学的研究内容 计算机图形学(Computer Graphics): 研究通过计算机将数据转换为图形,并在专用显示设备上显示的原理、方法和技术的学科。 计算机图形表现形式 (1).线条式(线框架图)

用线段来表现图形,容易反映客观实体的内部结构,如各类工程技术中结构图的表示,机械设计中零件结构图及电路设计中的电路原理图等。具有面模型、色彩、浓淡和明暗层次效应,适合表现客观实体的外形或外貌,如汽车、飞机、轮船等的外形设计以及各种艺术品造型设计等。 (2).真实感面模型图形 跑车靓照 计算机图形分类(空间) (1).二维图形(2D):在平面坐标系中定义的图形 (2).三维图形(3D):在三维坐标系中定义的图形 计算机图形产生方法 (1).矢量法(短折线法) 任何形状的曲线都用许多首尾相连的短直线(矢量)逼近。 (2).描点法(像素点串接法) 每一曲线都是由一定大小的像素点组成 计算机绘图方式: (1)交互式绘图 允许操作者以某种方式(对话方式或命令方式)来控制和操纵图形生成过程,使得图形可以边生成、边显示、边修改,直至符合要求为止。如AUTOCAD等 (2)被动式绘图 图形在生成过程中,操作者无法对图形进行操作和控制。如C语言绘图 图形的操作与处理方法(Picture Manipulation) 如图形的开窗、裁剪、平移、旋转、放大、缩小、投影等各种几何变换操作的方法及其 软件或硬件实现技术。 图形信息的存储,检索与交换技术:如图形信息的各种表示方法、组织形式、存取技术、图形数据库的管理、图形信息通信等。 人机交互及用户接口技术:如新型定位设备、选择设备的研究;

计算机图形学实验二报告

计算机图形学课实验 报告 题目: C程序绘图基础 专业 学生姓名 班级学号 指导教师 指导单位 日期

C程序绘图基础 一、内容与目的 内容: 1.编写一辆自行车在一公路上由右至左快速行驶的程序。 2.试自行设计一个美术图案,并且用程序实现。 目的: 1、掌握用Turbo C绘图时的步骤。 2、掌握C语言中的基本绘图函数及其用法。 3、掌握简单动画的实现方法。 二、基本设计思想 1、为了调用C语言提供的图形库函数,在程序的开头写上文件的包含命令; # include 2、图形系统初始化及关闭图形方式 初始化是通过调用 initgraph( )函数来完成,它的调用格式为: initgraph (* gdriver,* gmode,* path); 该函数的功能是通过从磁盘上装入一个图形驱动程序来初始化图形系统,并将显示器设置到指定图形方式下。参数gdriver, gmode, path的含义参见教材的有关章节。 在运行图形程序结束后,又要回到文本方式,以进行其它工作,这时应关闭图形方式。其格式为:closegraph( )。 3、图形显示器的工作方式 1)文本模式与字符坐标系 在未通过图形初始化之前的屏幕上,只能显示字符的方式称为文本模式。C语言能在指定位置显示字符,该坐标系以屏幕的左上角为坐标原点,水平向为x轴,自左向右;垂直方向为y轴,自上向下,坐标原点为(1,1)。能显示的行数、列数及颜色与显示方式有关。Turbo C支持6种不同的文本显示方式。 2)图形模式与点坐标系 在屏幕上能显示图形的方式称为图形方式。屏幕是由像素点组成的,通过initgraph 函数的gmode参数来指定屏幕的分辨率,分辨率决定了像素点的多少。 在图形方式下,屏幕上每个像素的显示位置用点坐标系来描述。在该坐标系中,屏幕的左上角为坐标原点O(0,0),水平向为x轴,自左向右;垂直方向为y轴,自上向下。如图1-1所示。 分辨率不同,水平方向和垂直方向上的点数也不一样,即其maxx、maxy的数值不同。在Turbo C中,坐标数据有两种形式给出:一种是绝对坐标;另一种是相对坐标。绝对坐标的参考点是坐标的原点O(0,0),x 和y的值只能取规定范围内的正整数,其坐标值在整个屏幕范围内确定。相对坐标是相对于“当前点”的坐标,所以其参考点不是坐标系的原点,而是当前点。要相对坐标中,x和y的取值是相对于当前点在X方向和Y方向上的增量,这个增量可以是正的,也可以是负的,所以x和y的值可以是正整数,也可以是负

计算机图形学实验报告实验2裁剪算法实验

一、实验目的: 直线段的裁剪:编码裁剪算法,中点分割裁剪算法。 二、实验内容: //BasicGraph.cpp //请将下列裁剪程序补充完整,并用注释说明是何种裁剪算法 void Encode (int x,int y,int *code,int XL,int XR,int YB,int YT) { //请将此程序补充完整 int c=0; if(xXR) c=c|RIGHT; if(yYT) c=c|TOP; (*code)=c; } //编码裁剪算法: void C_S_Line(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) { //请将此程序补充完整 int x1,x2,y1,y2,x,y,code1,code2,code; x1=p1.x; x2=p2.x; y1=p1.y; y2=p2.y; Encode(x1,y1,&code1,XL,XR,YB,YT); Encode(x2,y2,&code2,XL,XR,YB,YT); 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);} else if((RIGHT&code)!=0) {x=XR;y=y1+(y2-y1)*(XR-x1)/(x2-x1);} if((BOTTOM&code)!=0) {y=YB;x=x1+(x2-x1)*(YB-y1)/(y2-y1);} else if((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);} else {x2=x;y2=y;Encode(x,y,&code2,XL,XR,YB,YT);} }

计算机图形学实验报告

计算机图形学实验报告 计算机图形学实验报告 引言 计算机图形学是研究计算机生成和处理图像的学科,它在现代科技和娱乐产业中扮演着重要的角色。本实验报告旨在总结和分享我在计算机图形学实验中的经验和收获。 一、实验背景 计算机图形学实验是计算机科学与技术专业的一门重要课程,通过实践操作和编程,学生可以深入了解图形学的基本原理和算法。本次实验主要涉及三维图形的建模、渲染和动画。 二、实验内容 1. 三维图形建模 在实验中,我们学习了三维图形的表示和建模方法。通过使用OpenGL或其他图形库,我们可以创建基本的几何体,如立方体、球体和圆柱体,并进行变换操作,如平移、旋转和缩放。这些基本操作为后续的图形处理和渲染打下了基础。 2. 光照和着色 光照和着色是图形学中重要的概念。我们学习了不同的光照模型,如环境光、漫反射和镜面反射,并了解了如何在三维场景中模拟光照效果。通过设置材质属性和光源参数,我们可以实现逼真的光照效果,使物体看起来更加真实。3. 纹理映射 纹理映射是一种将二维图像映射到三维物体表面的技术。通过将纹理图像与物

体的顶点坐标相对应,我们可以实现更加细致的渲染效果。在实验中,我们学 习了纹理坐标的计算和纹理映射的应用,使物体表面呈现出具有纹理和细节的 效果。 4. 动画和交互 动画和交互是计算机图形学的重要应用领域。在实验中,我们学习了基本的动 画原理和算法,如关键帧动画和插值技术。通过设置动画参数和交互控制,我 们可以实现物体的平滑移动和变形效果,提升用户体验。 三、实验过程 在实验过程中,我们首先熟悉了图形库的使用和基本的编程技巧。然后,我们 按照实验指导书的要求,逐步完成了三维图形建模、光照和着色、纹理映射以 及动画和交互等任务。在实验过程中,我们遇到了许多挑战和问题,但通过不 断的尝试和调试,最终成功实现了预期的效果。 四、实验结果 通过实验,我们成功实现了三维图形的建模、渲染和动画效果。我们可以通过 键盘和鼠标控制物体的移动和变形,同时观察到真实的光照效果和纹理映射效果。实验结果符合预期,并且在实验报告中附上了实验截图和代码片段供参考。 五、实验总结 通过本次计算机图形学实验,我深入了解了三维图形的建模和渲染原理,掌握 了OpenGL等图形库的使用方法。同时,我也学会了如何应用光照、纹理映射 和动画等技术,使图形更加真实和生动。通过实验,我不仅提升了编程能力, 还培养了团队合作和问题解决的能力。 六、展望未来

计算机图形学中二维裁剪算法的研究

计算机图形学中二维裁剪算法的研究 随着计算机技术的发展,计算机图形学也日益成熟。在我们的日常生活中,也成了随处可见的必需部分。在医学、娱乐、图形艺术、商业、教育培训、科学工程等众多领域,计算机图形学的应用非常普遍。 计算机图形学主要研究的是在计算机中构造图形,将用数学模型描述的图形数据采用合适的算法转换为屏幕上图形的显示。计算机图形学学科研究的对象为二维图形学和三维图形学及其显示和变化情况。点、线、面为二维图形学范畴,几何体和场等数学构造方法则为三维图形学范畴。 现在,计算机图形学的一些基本算法已经形成了固化在硬件中的规范软件包,这个学科也日趋成熟和完善。但是依然有很多算法还需要不断的改进才能应用到实际中,而裁剪算法就是其中之一。本文主要对二维图形裁剪中的椭圆形窗口裁剪算法进行了研究,使其具有较高的效率和稳定性。 标签:计算机图形学裁剪算法椭圆形窗口线裁剪算法 1 裁剪概述 裁剪算法,简称裁剪,是计算机图形学中很多重要问题的基础,它就是从数据集合中识别指定区域内或指定区域外图形部分的过程。裁剪用途很广泛,最典型的就是确定场景中位于指定区域内的景物部分。其中,指定区域成为裁剪窗口,一般为矩形,由四条边组成,上、下、左、右,即:(Xl,Yb),(Xr,Yt)。实质上来说,裁剪就是确定哪些多边形等几何体位于裁剪窗口内。对于点(X,Y),只要判断两对不等式:Xl≤X≤Xr,Yb≤Y≤Yt即可。 如果四个点坐标的不等式都不成立,则这个点在矩形窗口外,否则,在窗口内。有一种最简单的裁剪方法,就是将所有图形扫描转换成点,然后在进行判断。但是这种方法时间消耗太大,非常不可取。倘若将全部在窗口外的图形完全排除而不进行扫描转换,则时间上面可以高效很多,故一般采用先裁剪再扫描的方法。 按裁减对象来分,裁剪算法大概分为如下几种:点裁剪、直线段裁剪、区域多边形裁剪、曲线裁剪和文字裁剪。 裁剪有多方面应用,主要包括:使用实体造型创建对象、在三维视图中标示出可见面、对图形的一部分进行删除、复制或移动操作、防止图形边界混淆、从特定场景中抽取指定部分等。在不同的应用中,裁剪窗口的形状也不尽相同。然而,裁剪算法是否高效关键在减少求交运算,高效识别裁剪线段是否与裁剪窗口边界相交。 二维裁剪算法分为两种,对二维线段的裁剪以及对二维多边形的裁剪,在这两方面,国内外许多专家学者都进行了深入的研究,出现了很多经典算法。对于

计算机图形学学习心得_学习心得体会_

计算机图形学学习心得 计算机图形学是20世纪60年代以后,随着计算机技术(包括计算机硬件技术和软件技术)的发展和完善而形成的一门新兴学科。下面是小编为大家收集整理的计算机图形学学习心得,欢迎大家阅读。 计算机图形学学习心得篇1 一、实验目的 了解梁友栋算法和编码裁剪算法并利用该算法思想实现某一图形或直线段的裁剪,加深对梁友栋算法和编码裁剪算法的理解。 二、实验内容 利用梁友栋算法(参数化线段裁剪算法)或编码裁剪算法变成实现对直线段或者任一图形的裁剪。 三、实验原理 梁友栋算法简介如下: 设线段两端点坐标分别为P1(x1,y1)和P2(x2,y2),则其参数化直线方程可写成下列形式: 0≤u≤1 当u=0时,得点P1,当u=1时,得点P2。线段的裁剪条件可以由下面的不等式表示:Wxl≤x1﹢uΔx≤Wxr;Wyb≤y1﹢uΔy≤Wyt 这四个不等式可以表示为:upk≤qk k=1,2,3,4 其中,参数p,q定义为: p1﹦-Δx, q1﹦x1﹣Wxl p2﹦Δx, q2﹦Wxr﹣x1 p3﹦-Δy, q3﹦y1﹣Wyb p4﹦Δy, q4﹦Wyt﹣y1 下标k=1,2,3,4分别对应裁剪窗口的左、右、下、上四条边界线。如果线段平行于裁剪窗口的某两边界,则必有相应的pk﹦0,如果还满足qk<0,则线段的端点位于窗口外部,即线段在窗口外,应该舍弃。如果qk≥0,线段在窗口内。当pk<0时,直线是从裁剪窗口第k条边界线的外部延伸到内部。当pk>0时,直线是从裁剪窗口第k条边界

线的内部延伸到外部。当pk不等于零时,可以计算出线段与第k条裁剪窗口边界线的交点参数:根据定义,对于每条线段,pk中必有两个小于零,而另两个大于零。对于小于零的pk,直线同第k条裁剪窗口边线是从外到内相遇的,此时如果线段同第k条裁剪窗口边界线有交点的话,是参数u从0变大时遇到的,这时计算出相应的rk值,取0和各个rk值之中的最大值记为u1。与此相反,对于大于零的pk,计算出相应的rk值,取1和各个rk值之中的最小值记为u2。两个参数u1和u2定义了在裁剪窗口内的线段部分。如果u1>u2,则线段完全落在裁剪窗口之外,应被舍弃。否则被裁剪线段可见部分的端点由参数u1和u2计算出来。 四、实验环境 Windows XP VisualC++6.0 五、实验步骤 进入VisualC++6.0环境,在菜单中选择“FileàNewàProjects”,然后选择“MFCAppWizard(exe)”新建一个工程文件单击“OK”,在弹出的对话框中选择“Single document”,单击“Finish”,在VisualC++6.0编程界面中选择CMyView单击右键,选择“Add Member Function”,在弹出的对话框中添写“void”和函数名。 // 图形裁减View.cpp : implementation of the CMyView class // #include "stdafx.h" #include "图形裁减.h" #include "图形裁减Doc.h" #include "图形裁减View.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE = __FILE__; #endif ///////////////////////////////////////////////////////////////////

计算机图形学编码裁剪算法c语言程序

编码裁剪算法 一,实验名称:编码裁剪算法 二,实验目的和意义:窗口内的图形显示,超出窗口边框的图形不予显示。这个过程就是裁剪过程,它在图形显示及窗视口变换中经常用到,对工程图形进行裁剪时,编码裁剪是一种有效的裁剪方法,通过该实验,了解和掌握编码裁剪的原理和方法。从而快速地处理显示区内的图形。 三,实验原理;将绘图所在平面分成九个区域,每 个区域用一个四位的二进制数来表示,0000、 0001、0010、1001、1000、1010、0101、0100、 0110,如果线段两个端点的4位编码全为0,表 示线段全部在窗口内,可直接接受并加以显示; 如果对线段两个端点的4位编码进行逻辑与运 算,结果为非0,则此线段全部在窗口外,可直 接舍弃加以裁减;否则,计算直线和窗口边框 线的交点,再计算交点的特征码;重复这一过 程,直到全部线段均被裁减掉或接受为止。 四,实验内容; 算法改编成C语言程序,给定一窗口区域(50,50,200,100),随机生成5条直线,对其进行裁剪处理,将处理结果加以显示。 五,算法步骤; 给定一窗口区域。 计算各区的特征码。 随机给定一条直线的两端上。 计算两端点对应的特征码。 如果两端点都在窗口内,直接显示。 如果有端点在窗口外,则判断它和哪个边框有交点。求出直线和对应边框线交点。在计算交点的特征码,重复前面的。 六,程序代码; /*说明;(x1,y1)和(x2,y2)为线段的两个端点。*/ #include"graphics.h" #include"stdio.h" #include"math.h" #define LEFT 1 #define RIGHT 2 #define BOTTOM 4 #define TOP 8 int x1=50,y1=50,x2=450,y2=350,xl=100,x r=400,yb=300,yt=100; int encode(int x,int y,int*code) { int c; c=0; if(xxr) c=RIGHT; if(y>yb)

计算机图形学-实验五直线和多边形的裁剪

大学实验报告 学院:计算机科学与信息学院专业:软件工程班级:102班 ** 实验组实验时间指导教师成绩实验工程名称实验五直线和多边形的裁剪 实 验 目 的 掌握直线段的裁剪算法以及多边形的裁剪算法 实 验要求熟练掌握直线段的裁剪算法以及多边形的裁剪算法的根本原理,并编写测试代码进展实验。 实验原理 Cohen-Sutherland直线剪裁算法 以区域编码为根底,将窗口及其周围的,8个方向以4 bit的二进制数进展编码。 右图所示的编码方法将窗口及其邻域 分为5个区域: ⑴域:区域(0000)。 ⑵上域:区域(1001, 1000, 1010)。 ⑶下域:区域(0101, 0100, 0110)。 ⑷左域:区域(1001, 0001, 0101)。 ⑸右域:区域(1010, 0010, 0110)。 当线段的两个端点的编码的逻辑"与〞非零时,线段为显然不可见的,对*线段的两个端点的区号进展位与运算,可知这两个端点是否同在视区的上、下、左、右; Cohen-Sutherland直线剪裁算法的算法思想是: 对于每条线段P1P2分为三种情况处理。〔1〕假设P1P2完全在窗口,则显示该线段P1P2简称"取〞之。〔2〕假设P1P2明显在窗口外,则丢弃该线段,简称"弃〞之。〔3〕假设线段既不满足"取〞的条件,也不满足"弃〞的条件,则在交点处把线段分为两段。其

while (code1 != 0 || code2 != 0) { if ((code1 & code2) != 0) {// 两端点的编码相与不为0,表示直线在窗口外return; } if (code1 != 0) { code = code1; } else { code = code2; } if ((LEFT & code) != 0) {// 直线的端点与矩形窗口的左边编码相与!=0 * = *L; y = y1 + (y2 - y1) * (*L - *1) / (*2 - *1);// 求直线与矩形窗口的左边界的交点 } elseif ((RIGHT & code) != 0) {// 直线的端点与矩形窗口的右边编码相与!=0 * = *R; y = y1 + (y2 - y1) * (*R - *1) / (*2 - *1);// 求直线与矩形窗口的右边界的交点 } elseif ((BOTTOM & code) != 0) {// 直线的端点与矩形窗口的下边编码相与!=0 y = YB; * = *1 + (*2 - *1) * (YB - y1) / (y2 - y1);// 求直线与矩形窗口的下边界的交点 } elseif ((TOP & code) != 0) {// 直线的端点与矩形窗口的上边编码相与!=0 y = YT; * = *1 + (*2 - *1) * (YT - y1) / (y2 - y1);// 直线的端点与矩形窗口的上

cohensutherland裁剪算法实验报告

cohensutherland裁剪算法实验报告 Cohen-Sutherland裁剪算法是一种用于计算机图形学中线段裁剪的算法。该算法用于确定一个给定的线段是否跨越了一个裁剪窗口,并且在必要的情况下将该线段裁剪到窗口内。Cohen-Sutherland算法是一种基于二进制编码的线框裁剪算法,其运算速度很快,广泛应用于计算机图形学中。 实验内容: 本次实验主要内容是使用Cohen-Sutherland裁剪算法对线段图形进行裁剪。具体实验过程如下: 1. 对于给定的线段和裁剪窗口,首先需要对线段进行编码。 2. 判断线段是否在裁剪窗口内。如果线段的两个端点都在裁剪窗口内,则该线段完全位于裁剪窗口内,不需要进行裁剪。 3. 如果线段的两个端点都在裁剪窗口外,则该线段完全位于裁剪窗口外,在此情况下可以直接将该线段丢弃。 4. 如果线段的一个端点在裁剪窗口内,而另一个端点在裁剪窗口外,则需要对该线段进行裁剪。

5. 根据线段的编码,在裁剪窗口的不同区域内确定该线段与裁剪窗口的相交点。 6. 在裁剪窗口内,将线段裁剪到与裁剪窗口相交的部分,并输出裁剪后的线段。实验步骤: 本次实验使用Python语言编写程序,具体代码实现如下: # 定义裁剪窗口的左,下,右,上位置 LEFT = 100 BOTTOM = 100 RIGHT = 500 TOP = 400 # 定义编码区域 INSIDE = 0 LEFT_EDGE = 1 RIGHT_EDGE = 2 BOTTOM_EDGE = 4 TOP_EDGE = 8

# 定义裁剪函数 def cohen_sutherland(x1, y1, x2, y2): # 对线段进行编码 code1 = encode(x1, y1) code2 = encode(x2, y2) accept = False while True: # 如果两端点都在裁剪窗口内 if code1 == INSIDE and code2 == INSIDE: accept = True break # 如果两端点都不在裁剪窗口内 elif (code1 & code2) != 0: break # 如果有一个端点在裁剪窗口内,但另一个端点不在 else: x = 0 y = 0 if code1 != INSIDE: code_out = code1 else:

计算机图形学 实验四 二维图形的裁剪

西北农林科技大学实习报告 学院名称:理学院专业班级: 姓名:学号: 课程:计算机图形学实验报告日期: 第十五周实验四二维图形的裁剪 一、实验目的 1)加深直线段的剪裁算法的理解。 2)熟练掌握一种裁剪算法的编程方法。 二、实验步骤 1)分析直线段和矩形窗口的位置关系,选定比较合理算法流程。 2)画出程序流程图。 3)编写程序的源程序。 4)编辑源程序并进行调试。 5)进行特殊模式的运行测试,并结合情况进行调整。 三、实验内容 1)在编码算法、中点分割算法、Liang-Barsky算法三种中任选一种作为编程模型。 2)编写直线段裁剪的源程序。 3)建议有能力的学生编写多边形裁剪程序。 4)在计算机上编辑编译运行,实现直线段的裁剪。 原理 1.直线和窗口的关系: 直线和窗口的关系可以分为如下3类: (1)整条直线在窗口内。此时,不需剪裁,显示整条直线。 (2)整条直线在窗口外,此时,不需剪裁,不显示整条直线。 (3)部分直线在窗口内,部分直线在窗口外。此时,需要求出直线与窗框的交点,并将窗口外的直线部分剪裁掉,显示窗口内的直线部分。

直线剪裁算法有两个主要步骤。首先将不需剪裁的直线挑出,即删去在窗外的直线。然后,对其余直线,逐条与窗框求交点,并将窗口外的部分删去。 2.Cohen-Sutherland直线剪裁算法: (1)输入直线段的两端点坐标p1(x1,y1),p2(x2,y2),以及窗口的4条边 界坐标,y w t ,y w b ,y w l ,y w r . (2)对p1,p2进行编码,点p1的编码为code1,点p2的编码为code2. (3)若code1| code2=0,对直线p1p2“简取”之,转(6);否则,若code1& code2≠0,对直线段“简弃”之,转(7);当上述两条均不满足时,进行步骤(4)。 (4)确保p1在窗口外部。若p1在窗口内,则交换p1和p2的坐标值和编码。 (5)根据p1编码从低位开始寻找值为1的地方,从而确定p1在窗口外的哪一侧,然后求出直线段与相应窗口边界的交点S,并用交点S的坐标值替换p1的坐标值,即在交点S处把线段一分为二,因此可以去掉p1S。转(2)。 (6)用直线扫描算法转换算法画出当前的直线段p1p2。 (7)算法结束。 图形描述: 在MATLAB中输入: >> W=[3,7,2,5] W = 3 7 2 5 >> P=[0,0,16,16] P = 0 0 16 16 >> r=CSCutLine(W,P) r = 1

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

裁剪算法详解 在使用计算机处理图形信息时,计算机内部存储的图形往往比较大,而屏幕显示的只是图的一部分。因此需要确定图形中哪些部分落在显示区之内,哪些落在显示区之外,以便只显示落在显示区内的那部分图形。这个选择过程称为裁剪。最简单的裁剪方法是把各种图形扫描转换为点之后,再判断各点是否在窗内。但那样太费时,一般不可取。这是因为有些图形组成部分全部在窗口外,可以完全排除,不必进行扫描转换。所以一般采用先裁剪再扫描转换的方法。 (a)裁剪前(b) 裁剪后 图1.1 多边形裁剪 1直线段裁剪 直线段裁剪算法比较简单,但非常重要,是复杂图元裁剪的基础。因为复杂的曲线可以通过折线段来近似,从而裁剪问题也可以化为直线段的裁剪问题。常用的线段裁剪方法有三种:Cohen-Sutherland,中点分割算法和梁友栋-barskey算法。 1.1 Cohen-Sutherland裁剪 该算法的思想是:对于每条线段P 1P 2 分为三种情况处理。(1)若P 1 P 2 完 全在窗口内,则显示该线段P 1P 2 简称“取”之。(2)若P 1 P 2 明显在窗口外,则 丢弃该线段,简称“弃”之。(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 #define TOP 8 int encode(float x,float y) { int c=0; if(xXR) c|=RIGHT; if(x

图形学实验报告

图形学实验报告

计 算 机 图 形 学 实验指导书 学号:1441901105 姓名:谢卉

实验一:图形的几何变换 实验学时:4学时 实验类型:验证 实验要求:必修 一、实验目的 二维图形的平移、缩放、旋转和投影变换(投影变换可在实验三中实现)等是最基本的图形变换,被广泛用于计算机图形学的各种应用程序中,本实验通过算法分析以及程序设计实验二维的图形变换,以了解变换实现的方法。如可能也可进行裁剪设计。 二、实验内容 掌握平移、缩放、旋转变换的基本原理,理解线段裁剪的算法原理,并通过程序设计实现上述变换。建议采用VC++实现OpenGL程序设计。 三、实验原理、方法和手段 1.图形的平移 在屏幕上显示一个人或其它物体(如图1所示),用交互操作方式使其在屏幕上沿水平和垂直方向移动Tx和Ty,则有 x’=x+Tx y’=y+Ty 其中:x与y为变换前图形中某一点的坐标,x’和y’为变换后图形中该点的坐标。其交互方式可先定义键值,然后操作功能键使其移动。 2.图形的缩放 在屏幕上显示一个帆船(使它生成在右下方),使其相对于屏幕坐标原点缩小s倍(即x方向和y方向均缩小s倍)。则有: x’=x*s y’=y*s

注意:有时图形缩放并不一定相对于原点,而是事先确定一个参考位置。一般情况下,参考点在图形的左下角或中心。设参考点坐标为xf、yf则有变换公式 x’=x*Sx+xf*(1-Sx)=xf+(x-xf)*Sx y’=y*Sy+yf*(1-Sy)=yf+(y-yf)*Sy 式中的x与y为变换前图形中某一点的坐标,x’和y’为变换后图形中该点的坐标。当Sx>1和Sy>1时为放大倍数,Sx<1和Sy<1时为缩小倍数(但Sx 和Sy必须大于零)。 3.图形的旋转 在屏幕上显示一个汽车,根据自己确定的旋转角度和旋转中心对图形进行旋转。旋转公式为 x’=xf+(x-xf)*cos(angle)-(y-yf)*sin(angle) y’=yf+(y-yf)*cos(angle)+(x-xf)*sin(angle) 其中:xf,yf为围绕旋转的中心点的坐标。x,y为旋转前图形中某点的坐标,x’和y’为旋转后图形中该点的坐标。 4.裁剪 对一个三角形进行裁剪,裁剪后的图形应是一个封闭的图形。可采用线段裁剪法,其方法可用书上的线段相交求点的公式,确定可见线段予以保存,不在窗口的线段则应舍弃。

相关主题