作者 : 卿笃军
原文地址: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版) 孔令德 编著
时间: 2024-10-09 07:05:31