首页 > 代码库 > 计算机图形学 Cohen-Sutherland直线段裁剪算法

计算机图形学 Cohen-Sutherland直线段裁剪算法

作者 : 卿笃军

原文地址:http://blog.csdn.net/qingdujun/article/details/40822977


本文通过一个完整的实例演示Cohen-Sutherland直线段裁剪算法。


1)创建类CP2

头文件:P2.h

// P2.h: interface for the CP2 class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_P2_H__23095C49_598D_4E8D_B510_87490878E0F6__INCLUDED_)
#define AFX_P2_H__23095C49_598D_4E8D_B510_87490878E0F6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CP2  
{
public:
	CP2();
	virtual ~CP2();
public:
	int x;
	int y;
	int rc;
};

#endif // !defined(AFX_P2_H__23095C49_598D_4E8D_B510_87490878E0F6__INCLUDED_)
实现文件:p2.cpp

// P2.cpp: implementation of the CP2 class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Cohen_Sutherland.h"
#include "P2.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CP2::CP2()
{
	x = 0;
	y = 0;
	rc = 0;
}

CP2::~CP2()
{

}
2)工程类CCohen_SutherlandView

头文件:Cohen_SutherlandView.h

// Cohen_SutherlandView.cpp : implementation of the CCohen_SutherlandView class
//

#include "stdafx.h"
#include "Cohen_Sutherland.h"

#include "Cohen_SutherlandDoc.h"
#include "Cohen_SutherlandView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define LEFT    1   //0001
#define RIGHT   2   //0010
#define BOTTOM  4   //0100
#define TOP     8   //1000


/////////////////////////////////////////////////////////////////////////////
// CCohen_SutherlandView

IMPLEMENT_DYNCREATE(CCohen_SutherlandView, CView)

BEGIN_MESSAGE_MAP(CCohen_SutherlandView, CView)
//{{AFX_MSG_MAP(CCohen_SutherlandView)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCohen_SutherlandView construction/destruction

CCohen_SutherlandView::CCohen_SutherlandView()
{
	// TODO: add construction code here
	flag = 0;
	XL = XR = YT = YB = 0;
	p0.x = p0.y = 50;	
	p1.x = p1.y = 300;
}

CCohen_SutherlandView::~CCohen_SutherlandView()
{
}

BOOL CCohen_SutherlandView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	
	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CCohen_SutherlandView drawing

void CCohen_SutherlandView::OnDraw(CDC* pDC)
{
	CCohen_SutherlandDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	if (1 == flag)
	{
		pDC->Rectangle(CRect(XL,YT,XR,YB));//画出剪切窗口
	}
	pDC->MoveTo(p0.x,p0.y);
	pDC->LineTo(p1.x,p1.y);
}

/////////////////////////////////////////////////////////////////////////////
// CCohen_SutherlandView diagnostics

#ifdef _DEBUG
void CCohen_SutherlandView::AssertValid() const
{
	CView::AssertValid();
}

void CCohen_SutherlandView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CCohen_SutherlandDoc* CCohen_SutherlandView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCohen_SutherlandDoc)));
	return (CCohen_SutherlandDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CCohen_SutherlandView message handlers

void CCohen_SutherlandView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	flag = 1;
	XL = point.x;
	YT = point.y;
	
	CView::OnLButtonDown(nFlags, point);
}

void CCohen_SutherlandView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (flag == 1)
	{
		XR = point.x;
		YB = point.y;
		Invalidate();
	}
	
	CView::OnMouseMove(nFlags, point);
}

void CCohen_SutherlandView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	flag = 0;
	LineCut();
	XL = XR = YT = YB = 0;
	Invalidate();

	CView::OnLButtonUp(nFlags, point);
}
//端点编码
void CCohen_SutherlandView::EnCode(CP2 &pt)
{
	pt.rc = 0;
	if (pt.x < XL)
	{
		pt.rc |= LEFT;  //0001=1
	}
	else if (pt.x > XR)
	{
		pt.rc |= RIGHT; //0010=2
	}
	if (pt.y > YB)
	{
		pt.rc |= BOTTOM;//0100=4
	}
	else if (pt.y < YT)
	{
		pt.rc |= TOP;   //1000=8
	}
}
//裁剪直线-Conhen-Sutherland算法
void CCohen_SutherlandView::LineCut() 
{
	int x,y;
	CP2 pt0 = p0, pt1 = p1;

	while (1)
	{
		//端点编码
		EnCode(p0);
		EnCode(p1);

		//全部在窗体内“简取”
		if(0 == (p0.rc | p1.rc))
		{
			return;
		}
		//全部在窗体外“简弃”
		else if(0 != (p0.rc & p1.rc))
		{
			p0 = pt0;
			p1 = pt1;
			return;
		}
		else
		{
			if(0 == p0.rc)//如果p0点在窗口内,交换p0和p1,保证p0点在窗口外
			{
				CP2 pt = p0;
				p0 = p1;
				p1 = pt;
			}
			//按左、右、下、上的顺序裁剪
			if(p0.rc & LEFT)//p0点位于窗口的左侧
			{
				x = XL;
				y = (p1.y-p0.y)/(p1.x-p0.x)*(x-p0.x)+p0.y;
			}			
			else if(p0.rc & RIGHT)//p0点位于窗口的右侧
			{
				x = XR;
				y = (p1.y-p0.y)/(p1.x-p0.x)*(x-p0.x)+p0.y;
			}				
			else if(p0.rc & BOTTOM)//p0点位于窗口的下侧
			{
				y = YB;
				x = (y-p0.y)/( (p1.y-p0.y)/(p1.x-p0.x) )+p0.x;
			}			
			else if(p0.rc & TOP )//p0点位于窗口的上侧
			{
				y = YT;
				x = (y-p0.y)/( (p1.y-p0.y)/(p1.x-p0.x) )+p0.x;
			}
			p0.x = x;	
			p0.y = y;
		}
	}
}

3)运行效果图:


源代码下载地址:http://download.csdn.net/detail/u012339743/8123725

原文地址:http://blog.csdn.net/qingdujun/article/details/40822977

参考文献:计算机图形学基础教程(Visual C++版)(第2版) 孔令德 编著


计算机图形学 Cohen-Sutherland直线段裁剪算法