计算机图形学 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版) 孔令德 编著

时间: 2024-10-09 07:05:31

计算机图形学 Cohen-Sutherland直线段裁剪算法的相关文章

计算机图形学 - 全斜率直线中点生成算法

算法描述: 直线中点生成算法 假定直线斜率k在(0,1]之间,当前像素点为,则下一个像素点有两种可选择点P1或P2. 若P1与 P2的中点称为M,Q为理想直线与x=xp+1垂线的交点. • 当M在Q的下方时,则取P2为下一个像素点: • 当M在Q的上方时,则取P1为下一个像素点. 这就是中点画线法的基本原理. 算术推导: 详细代码:Computer Graphics - code_1 生成结果:

计算机图形学(三种画线算法)

第二章:光栅图形学算法 1.光栅显示器:光栅扫描式图形显示器简称光栅显示器,是画点设备,可看作是一个点阵单元发生器,并可控制每个点阵单元的亮度 2.由来:随着光栅显示器的出现,为了在计算机上处理.显示图形,需要发展一套与之相适应的算法. 3.研究内容: 1>直线段的扫描转换算法 2>多边形的扫描转换与区域填充算法 3>裁剪算法 4>反走样算法 5>消隐算法 一.直线段的扫描转换算法 1.为了显示一条直线,就在光栅显示器上用离散的像素点逼近直线,所以我们就要知道这些像素点的坐标

[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)

一.首先说明: 这是啥? —— 这是利用C#FORM写的一个用来演示计算机图形学中 ①Bresenham直线扫描算法(即:连点成线):②种子填充法(即:填充多边形):③扫描线填充法 有啥用? ——  无论是连点成线还是区域填充在高级编程中基本上都提供很高效的库函数来调用.这里拿出这些算法一方面有利于大家理解那些封装的函数底层是实现:另一方面是方便嵌入式TFT屏幕底层驱动开发时借鉴的. 是啥样? ——  如下面的操作,不言而喻. 二.进入正题: 2-1.直线的扫描转换 图形的扫描转换实质就是在光栅

计算机图形学名词解释

转自 http://blog.csdn.net/lwfcgz/article/details/39254743 3D三维(three dimension).客观世界中静止的物体都是三维的,在计算机图形学中常在一定的坐标系中用(x,y,z)坐标系列表示物体. 3D modeling3D建模.用三维坐标来描述物体的形状.在各种计算机图形应用领域中有不同的三维建模方法,用不同的算法来描述这些领域中的物体和对象. 3D transformation3D变换.在三维空间中把物体的三维坐标从一个位置变换至另

【转载】计算机图形学框架

原文: 计算机图形学框架 应用 基本图形生成算法 图元光栅化标准 直线要直 图元终点要准 图元生成的亮度.色泽粗细要均匀 快速计算 直线光栅化算法 逐点比较法 数值微分法 中点Bresenham算法 圆的光栅化算法 简单方程产生圆弧 Bresenham算法产生圆弧 多边形填充 扫描线填充 宽图元 复制像素画宽图元 移动画笔画宽图元 3D数学基础 坐标系 向量 矩阵 空间集合运算 集合形体的表达 几何体之间的关系 图形变换 二维及三维图形几何变换 二维图形几何变换 平移变换 比例变换 旋转变换 错

清华版CG 实验4 编码裁剪算法

1.实验目的: 了解二维图形裁剪的原理(点的裁剪.直线的裁剪.多边形的裁剪),利用VC+OpenGL实现直线的裁剪算法. 2.实验内容: (1) 理解直线裁剪的原理(Cohen-Surtherland算法.梁友栋算法) (2) 利用VC+OpenGL实现直线的编码裁剪算法,在屏幕上用一个封闭矩形裁剪任意一条直线. (3) 调试.编译.修改程序. (4) 尝试实现梁友栋裁剪算法. 3.实验原理: 编码裁剪算法中,为了快速判断一条直线段与矩形窗口的位置关系,采用了如图A.4所示的空间划分和编码方案.

Cohen Sutherland裁剪算法并使用OpenGL实践

还是其几天写的,这是最简单的一个直线裁剪算法了吧,它针对的是一个矩形和一条线段.并且还是边与坐标轴平行的矩形. 在实际应用上应该会经常用于屏幕对各种线段的裁剪吧.算法很简单效率也很高. 首先是算法的两种特例:平凡接受和平凡拒绝. (图片来自<计算机图形学(OpenGL)>第三版) 当线段的两个端点都在矩形内部,则平凡接受,不需要裁剪.如图中的AB.而当线段的两个端点都在某条边的外边时,平凡拒绝,也不需要裁剪.如图中的CD. 检测这两种情况的方法可以先形成两个端点的码字,如下: 那么可以得到如下

计算机图形学 彩色直线段的反走样(5)

作者:卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/40083207 本文通过一个完整的例子来演示彩色直线段的反走样. 1)创建CP2类 头文件:P2.h // P2.h: interface for the CP2 class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_P2_H__DD23

计算机图形学 - 线段裁剪 - Liang Barsky算法(梁友栋算法)

算法描述: Liang_Barsky算法的基本出发点是直线的参数方程.给出任意一条直线段,两端点分别为和,令, 则直线的参数方程为: 如果直线上任意一点位于窗口内,则必须满足下列关系式: 上述不等式可以表示为: 其中p和q定义为: 任何一条直线如果平行于某一条裁剪边界,则有,下标k 对应于直线段平行的窗口边界(,并且分别表示裁剪窗口的左.右.下.上边界).如果对于某一个k值,满足,那么直线完全在窗口的外面,可以抛弃.如果,则该直线在它所平行的窗口边界的内部,还需要进一步计算才能确定直线是否在窗口