CohenSutherland直线裁剪算法.doc

上传人:b****1 文档编号:230048 上传时间:2022-10-07 格式:DOC 页数:9 大小:225.50KB
下载 相关 举报
CohenSutherland直线裁剪算法.doc_第1页
第1页 / 共9页
CohenSutherland直线裁剪算法.doc_第2页
第2页 / 共9页
CohenSutherland直线裁剪算法.doc_第3页
第3页 / 共9页
CohenSutherland直线裁剪算法.doc_第4页
第4页 / 共9页
CohenSutherland直线裁剪算法.doc_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

CohenSutherland直线裁剪算法.doc

《CohenSutherland直线裁剪算法.doc》由会员分享,可在线阅读,更多相关《CohenSutherland直线裁剪算法.doc(9页珍藏版)》请在冰豆网上搜索。

CohenSutherland直线裁剪算法.doc

实验三图形裁剪算法

1.实验目的:

理解区域编码(RegionCode,RC)

设计Cohen-Sutherland直线裁剪算法

编程实现Cohen-Sutherland直线裁剪算法

2.实验描述:

设置裁剪窗口坐标为:

wxl=250;wxr=850;wyb=250;wyt=450;裁剪前如下图所示:

裁剪后结果为:

3.算法设计:

Cohen-Sutherland直线裁剪算法:

假设裁剪窗口是标准矩形,由上(y=wyt)、下(y=wyb)、左(x=wxl)、右(x=wxr)四条边组成,如下图所示。

延长窗口四条边形成9个区域。

根据被裁剪直线的任一端点P(x,y)所处的窗口区域位置,可以赋予一组4位二进制区域码C4C3C2C1。

为了保证窗口内直线端点的编码为零,编码规则定义如下:

第一位:

若端点位于窗口之左侧,即x

第二位:

若端点位于窗口之右侧,即x>wxr,则C2=1,否则C2=0。

第三位:

若端点位于窗口之下侧,即y

第四位:

若端点位于窗口之上侧,即y>wyt,则C4=1,否则C4=0。

裁剪步骤:

1.若直线的两个端点的区域编码都为零,即RC1|RC2=0(二者按位相或的结果为零,即RC1=0且RC2=0),说明直线两端点都在窗口内,应“简取”之。

2.若直线的两个端点的区域编码都不为零,即RC1&RC2≠0(二者按位相与的结果不为零,即RC1≠0且RC2≠0,即直线位于窗外的同一侧,说明直线的两个端点都在窗口外,应“简弃”之。

3.若直线既不满足“简取”也不满足“简弃”的条件,直线必然与窗口相交,需要计算直线与窗口边界的交点。

交点将直线分为两段,其中一段完全位于窗口外,可“简弃”之。

对另一段赋予交点处的区域编码,再次测试,再次求交,直至确定完全位于窗口内的直线段为止。

4.实现时,一般按固定顺序左(x=wxl)、右(x=wxr)、下(y=wyb)、上(y=wyt)求解窗口与直线的交点。

4.源程序:

1)//TestView.h

classCTestView:

publicCView

{

…….

protected:

doublePointx[2],Pointy[2];//用户绘制的直线

int wxl,wxr,wyb,wyt;//左上与右下

CDC Picture;//内存(预存)DC,防止屏幕闪烁

char m_i;//第一个点还是第二个点

BOOL m_Attatch;

BOOL m_Draw;

unsignedintRC,RC0,RC1;

……..

}

2)//TestView.cpp

#defineROUND(a)int(a+0.5)

#defineLEFT1

#defineRIGHT2

#defineBOTTOM4

#defineTOP8

CTestView:

:

CTestView()

{

//窗口位置坐标

wxl=250;wxr=850;wyb=250;wyt=450;

m_Attatch=FALSE;

m_i=0;

m_Draw=FALSE;

RC0=0;RC1=0;

}

voidCTestView:

:

OnDraw(CDC*pDC)

{

CTestDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

CRectRect;

GetClientRect(&Rect);//获得客户区的大小

CBitmap Bitmap,*pBitmap;

Bitmap.LoadBitmap(IDB_BITMAP1);

CDC MemDC;

MemDC.CreateCompatibleDC(GetDC());

pBitmap=MemDC.SelectObject(&Bitmap);

MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),&Picture,0,0,SRCCOPY);

MemDC.TextOut((wxl+wxr)/2,wyb-20,"窗口");//窗口标题

//绘制窗口和直线

CPenPen3,*pOldPen3;//定义3个像素宽度的画笔

Pen3.CreatePen(PS_SOLID,3,RGB(0,0,0));

pOldPen3=MemDC.SelectObject(&Pen3);

MemDC.MoveTo(wxl,wyt);MemDC.LineTo(wxr,wyt);

MemDC.LineTo(wxr,wyb);MemDC.LineTo(wxl,wyb);

MemDC.LineTo(wxl,wyt);MemDC.SelectObject(pOldPen3);

Pen3.DeleteObject();

CPenPen1,*pOldPen1;//定义1个像素宽度的画笔

Pen1.CreatePen(PS_SOLID,1,RGB(0,255,255));

pOldPen1=MemDC.SelectObject(&Pen1);

if(m_i>=1)

{

MemDC.MoveTo(ROUND(Pointx[0]),ROUND(Pointy[0]));

MemDC.LineTo(ROUND(Pointx[1]),ROUND(Pointy[1]));

}

MemDC.SelectObject(pOldPen1);

Pen1.DeleteObject();

CDC*dc=GetDC();

dc->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);

MemDC.SelectObject(pBitmap);

}

voidCTestView:

:

OnMENUClip()//裁剪菜单函数

{

Cohen();

Invalidate(FALSE);

}

unsignedintCTestView:

:

EnCode(doubleLinePx,doubleLinePy)//端点编码函数

{//顺序左右下上

RC=0;

if(LinePx

{

RC=RC|LEFT;

}

if(LinePx>wxr)

{

RC=RC|RIGHT;

}

if(LinePy

{

RC=RC|BOTTOM;

}

if(LinePy>wyt)

{

RC=RC|TOP;

}

returnRC;

}

voidCTestView:

:

Cohen()//Cohen-Sutherland算法

{

BOOLChange;

doublex,y;

RC0=EnCode(Pointx[0],Pointy[0]);

RC1=EnCode(Pointx[1],Pointy[1]);

while(TRUE)

{

Change=FALSE;

if(0==(RC0|RC1))

{//简取之

return;

}

elseif(0!

=(RC0&RC1))

{//简弃之

return;

}

else

{

if(0==RC0)//如果P0点在窗口内,交换P0和P1,保证p0点在窗口外

{

//交换点的坐标值

doubleTPointx,TPointy;

TPointx=Pointx[0];TPointy=Pointy[0];

Pointx[0]=Pointx[1];Pointy[0]=Pointy[1];

Pointx[1]=TPointx;Pointy[1]=TPointy;

//交换点的编码值

unsignedintTRC;

TRC=RC0;RC0=RC1;RC1=TRC;

}

//按左、右、下、上的顺序裁剪

if(RC0&LEFT)//P0点位于窗口的左侧

{

x=wxl;//求交点y

y=Pointy[0]+(Pointy[1]-Pointy[0])*(x-Pointx[0])/(Pointx[1]-Pointx[0]);

Pointx[0]=x;Pointy[0]=y;

Change=TRUE;

RC0=EnCode(Pointx[0],Pointy[0]);RC1=EnCode(Pointx[1],Pointy[1]);

}

if(RC0&RIGHT)//P0点位于窗口的右侧

{

x=wxr;//求交点y

y=Pointy[0]+(Pointy[1]-Pointy[0])*(x-Pointx[0])/(Pointx[1]-Pointx[0]);

Pointx[0]=x;Pointy[0]=y;

Change=TRUE;

RC0=EnCode(Pointx[0],Pointy[0]);RC1=EnCode(Pointx[1],Pointy[1]);

}

if(RC0&BOTTOM)//P0点位于窗口的下侧

{

y=wyb;//求交点x

x=Pointx[0]+(Pointx[1]-Pointx[0])*(y-Pointy[0])/(Pointy[1]-Pointy[0]);

Pointx[0]=x;Pointy[0]=y;

Change=TRUE;

RC0=EnCode(Pointx[0],Pointy[0]);RC1=EnCode(Pointx[1],Pointy[1]);

}

if(RC0&TOP)//P0点位于窗口的上侧

{

y=wyt;//求交点x

x=Pointx[0]+(Pointx[1]-Pointx[0])*(y-Pointy[0])/(Pointy[1]-Pointy[0]);

Pointx[0]=x;Pointy[0]=y;

Change=TRUE;

RC0=EnCode(Pointx[0],Pointy[0]);RC1=EnCode(Pointx[1],Pointy[1]);

}

if(FALSE==Change)

{

return;

}

}

}

}

voidCTestView:

:

OnMENUDrawLine()//绘制直线菜单函数

{

//TODO:

Addyourcommandhandlercodehere

if(FALSE==m_Attatch)

{

Picture.CreateCompatibleDC(GetDC());

CBitmap *Bitmap,*pBitmap;

Bitmap=newCBitmap;

Bitmap->LoadBitmap(IDB_BITMAP1);

pBitmap=Picture.SelectObject(Bitmap);

m

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1