好文档 - 专业文书写作范文服务资料分享网站

计算机图形学 二维裁剪算法Cohen - Sutherland的实现

天下 分享 时间: 加入收藏 我要投稿 点赞

实验六 二维裁剪算法Cohen_Sutherland的实现 一、实验目的:

理解并掌握直线裁剪算法。使用Visual C++实现二维直线的裁剪的Cohen_Sutherland算法。对窗口进行编码,并实现相应的裁剪函数。

二、实验内容及要求:

1、 2、 3、

要求用消息映射的方式,绘制出一个裁剪窗口,大小为200×150象素;

按照例程的步骤画出3条典型线段,分别对应于完全在裁剪窗口内、完全在裁剪窗口外、穿过裁剪窗口三种情况,并按照本实验例程的方法用颜色分别表示出裁剪后的情况; 按要求撰写实验报告,写出实验心得,并在实验报告中附上程序的核心算法代码。

三、实验设备:

微机,Visual C++6.0

四、实验内容及步骤:

1、 打开VC,新建一个MFC Appwizard项目,选择创建单文档工程(SDI工程)。假设工程名为Clip。

如图1和图2所示。

图1

图2

2、 在图2的界面上点击Finish,完成工程的创建。

3、 在视图类ClipView中定义变量CRect rect; 用于记录裁剪窗口的位置; 4、 在ClipView.cpp文件中定义四个宏,记录裁剪窗口的上下左右四个位置: #define LEFT 100 #define RIGHT 300 #define TOP 150

#define BOTTOM 310

5、 在视图类的构造函数中为rect赋值; CClipView::CClipView() {

// TODO: add construction code here

rect = CRect(LEFT, TOP, RIGHT, BOTTOM); }

6、 在视图类(类CFillView中)的OnDraw()函数中绘制裁剪矩形,OnDraw函数的代码如下:

void CClipView::OnDraw(CDC* pDC) {

CClipDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

// TODO: add draw code for native data here pDC->Rectangle(&rect); }

7、 在视图类(类CFillView中)添加成员函数int Encode(int x, int y),该函数用于对线段的两个顶点

进行Cohen_Sutherland编码。函数体如下: int CClipView::Encode(int x, int y) {

int nCode = 0; if(x < LEFT) nCode = nCode | 0x01; if(x > RIGHT) nCode = nCode | 0x02; if(y > BOTTOM)

nCode = nCode | 0x04; if(y < TOP) nCode = nCode | 0x08; return nCode; }

8、 在视图类中添加Cohen_Sutherland裁剪算法的实现函数,函数体如下:

void CClipView::CLIP_Line_Cohen_Sutherland(CPoint &P1, CPoint &P2) {

int nCode1 = 0; int nCode2 = 0;

nCode1 = Encode(P1.x, P1.y); nCode2 = Encode(P2.x, P2.y); if(nCode1 ==0 && nCode2 ==0) return; //直线在裁剪窗口内,直接返回 else if((nCode1 & nCode2) != 0) { P1 = CPoint(0,0); P2 = CPoint(0,0); return; //直线在裁剪窗口外,将直线的两个端点赋为0,返回 }

double wx = P2.x - P1.x; double wy = P2.y - P1.y; double dX = 0; double dY = 0;

while(nCode1 != 0 || nCode2 != 0) { int nCode = nCode1; if(nCode1 == 0) nCode = nCode2; if((nCode & 0x01) == 0x01) //说明左边与边界有交点 { dX = LEFT; dY = P1.y + wy * (LEFT-P1.x)/wx; } else if((nCode & 0x02) == 0x02) //说明右边与边界有交点 { dX = RIGHT; dY = P1.y + wy * (RIGHT-P1.x)/wx; } else if((nCode & 0x04) == 0x04) //说明下边与边界有交点 { dX = (BOTTOM-P1.y) * wx / wy + P1.x; dY = BOTTOM;

} }

}

else if((nCode & 0x08) == 0x08) //说明上边与边界有交点 { dX = (TOP-P1.y) * wx / wy + P1.x; dY = TOP; }

if(nCode == nCode1) { P1 = CPoint((int)(dX+0.4),(int)(dY+0.4)); nCode1 = Encode(P1.x,P1.y); } else { P2 = CPoint((int)(dX+0.4),(int)(dY+0.4)); nCode2 = Encode(P2.x,P2.y); }

9、 映射菜单消息,方法是打开ResourceView菜单,依次展开MENU \\ IDR_MAINFRAME,添加“线

段裁剪”主菜单项,在其下添加“Cohen_Sutherland算法”,如图3所示。

图3 10、 在ClipView.cpp文件中(类CClipView中)映射“Cohen_Sutherland算法”的菜单消息,触

发Cohen_Sutherland裁剪函数。代码如下: void CClipView::OnClipLineCohenSutherland() {

// TODO: Add your command handler code here CPoint P1 = CPoint(80,400); CPoint P2 = CPoint(200,80); CDC *pDC = this->GetDC();

CPen newPen(PS_SOLID,2,RGB(255,0,0)); //用红色2个线宽绘制被裁剪初始直线 CPen *pOldPen=pDC->SelectObject(&newPen); pDC->MoveTo(P1); pDC->LineTo(P2);

pDC->SelectObject(pOldPen);

CLIP_Line_Cohen_Sutherland(P1,P2); P1P2中

CPen clipPen(PS_SOLID,2,RGB(0,0,255)); pOldPen=pDC->SelectObject(&clipPen); pDC->MoveTo(P1); pDC->LineTo(P2);

pDC->SelectObject(pOldPen); this->ReleaseDC(pDC); }

二维的Cohen_Sutherland算法实现完毕。

//用窗口裁剪P1P2直线,裁剪后的顶点保存在

//用蓝色2个线宽绘制窗口内裁剪之后的线段

五、核心代码:

这里将自己编写的上机程序中的主要代码拷贝粘贴过来;

定义:

#define LEFT 100 #define RIGHT 300 #define TOP 150

#define BOTTOM 310

OnDraw部分:

void CClipView::OnDraw(CDC* pDC) { CClipDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDC->Rectangle(&rect); OnClipLineCohenSutherland(); // TODO: add draw code for native data here }

int CClipView::Encode(int x, int y) { int nCode = 0; if(x < LEFT) nCode = nCode | 0x01; if(x > RIGHT)

599tw0wabz9x6b74310b
领取福利

微信扫码领取福利

微信扫码分享