计算机图形学——裁剪

裁剪作用:
选择显示的内容--图形在窗口内的部分被显示出来,窗口外的部分被裁剪掉
 图形中每个图形基本元素都要经过裁剪,因此裁剪直接影响整个图形系统的效率。

裁剪窗口:矩形,凸多边形,任意多边形
裁剪类型:二维裁剪、三维裁剪
裁剪对象:直线段、多边形、文字等
裁剪方法:
直线的裁剪方法: Sutherland-Cohen算法 , Cyrus-Beck算法,梁友栋-Barsky算法
多边形的裁剪方法:Sutherland-Hodgman算法
三维的裁剪方法: Sutherland-Cohen算法 ,梁友栋-Barsky算法

一、Sutherland-Cohen算法

本算法又称为编码裁剪算法

Sutherland–Cohen算法分成两部分:

第一步,判定:
1) 完全在窗口内的直线段,称为完全可见的线段,如AB。保留着
2) 完全在窗口外的线段,称为完全不可见线段,如CD。抛弃掉

第二步,处理不能断定为完全可见或完全不可见的线段,如IJ、KL
*这时需要计算出直线段和窗口边界的一个交点,这个交点把直线分成两段,其中一条为完全不可见的线段,被抛弃。
*对余下部分再作第一步的判断,重复上述过程,直到直线段余下的部分可用第一步的判断得出肯定的结论为止。

1、判断完全可见/不可见的线段

为使计算机能够快速判断一条直线段与窗口属何种关系,采用如下编码方法。窗口的四条边把整个平面分成九个区域,每一个区域采用四位编码表示:

在x=xL左侧的区域,编码的第四位是1;
在x=xR右侧的区域,编码的第三位是1;
在y=yB下侧的区域,编码的第二位是1;
在y=yT上侧的区域,编码的第一位是1。

如何判断?
对要被裁剪的线段的两个端点进行区域编码。

如果其所在的区域的编码均是0000(相与),则这条线段完全可见;
如果两个编码的逻辑与不为0000,则这条线段完全不可见

2、处理不能断定为完全可见或完全不可见的线段

线段KL为例,从K点(1001)的编码分析出K在x=xL的左侧,KL必和x=xL有交点,求出其交点M,KM显然是完全不可见的,因而只要对ML从第一步开始重复上述处理步骤。
由于ML还是不能用第一步下结论,又从M的编码发现M在y=yT的上侧,因而要求ML和y=yT的交点N。

丢掉MN,对NL用第一步的方法可断定NL为完全可见,至此裁剪结束。

3、程序代码

float xl, xr, yt, yb;
unsigned char code(float x, float y)
{
    unsigned char c = 0;
    if (x < xl)
        c = c|1;  //按位或
    else if (x > xr)
        c = c|2;
    if (y < yb)
        c = c|4;
    else if (y > yt)
        c = c|8;
    return c;
}//给九个区域编码
 
void clip(float x0, float y0, float x2, float y2)
{
    unsigned char c1, c2, c;
    float x, y, wx, wy;
    c1 = code(x0, y0);
    c2 = code(x2, y2);
    while ((!(c1 == 0)) || (!(c2 == 0)))
    {
        if ((c1& c2))
            return; //两端点逻辑与不为0,则在区域外,裁去
        c = c1;
        if (c == 0)
            c = c2;
        wx=x2-x0;
        wy=y2-y0;
        if ((c & 1) == 1)
        {
            y = y0 + wy * (xl - x0) /wx;
            x = xl;
        }//端点在xl左侧,求与xl的交点

        else if ((c & 2) == 2)
        {
            y = y0 +wy * (xr - x0) /wx;
            x = xr;
        } //端点在xr右侧,求与xr的交点

        else if ((c & 4) == 4)
        {
            x = x0 +wx * (yb - y0) /wy;
            y = yb;
        } //端点在yb下方,求与yb的交点

        else if ((c & 8) == 8)
        {
            x = x0 +wx * (yt - y0) / wy;
            y = yt;
        } //端点在yt上方,求与yt的交点

        if (c == c1)
        {
            x0 = x;
            y0 = y;
            c1 = code(x0, y0);
        }
        else
        {
            x2 = x;
            y2 = y;
            c2 = code(x2, y2);
        } //用交点代替端点,再返回第一步
    }// While()
    glLine(int(x0), int(y0), int(x2), int(y2));
}

4、小结

Cohen-Sutherland裁剪算法对不与边框相交的线段进行裁剪时效率较高,而对与窗口边界有交点的线段裁剪效率低。

因而比较适合两种情况的裁剪:一是大部分线段完全可见;二是大部分线段完全不可见。

而且很多的时候,被裁剪线段仅与窗口边界延长线相交,求交点到最后是无效的操作,因为线段可能完全被丢弃;并且被裁剪线段与窗口边界相交时交点的取得比较复杂。

比如像下图这样的裁剪,这条红色线段完全是在裁剪窗口的外部,却需要进行算法计算,最后线段完全被丢弃!

二、中点分隔算法

中点分隔算法是对Sutherland-Cohen算法在求交点方面的改进。

核心思想是通过二分逼近来确定直线段与 窗口的交点。

取线段的中点

1、若中点不在窗口内, 则把中点和离窗口边界最远点构成的线段丢掉,以线段上的另一点和该中点再构成线段求其中点

2、如中点在窗口内,则又以中点和最远点构成线段, 并求其中点,直到中点与窗口边界的 坐标值在规定的误差范围内相等

重复上述过程,直到线段长度小于给定的小数ε为止。
在显示时ε可取成一个象素的宽度,对分辨率为2N×2N的显示器来说,上面讲的二分的过程最多只要作N次

三、Cyrus-Beck算法

Cyrus-Beck算法可以处理任意凸多边形对线段的裁剪。

1、裁剪目标

考虑如图所示一个凸多边形区域R和一条线段P1P2,要求计算线段落在区域R中的部分。

2、线段表示

假定A是区域R边界L上一点;N是区域边界在A点的内法向量;线段P1P2用参数方程表示:

3、基本思想

对于线段P1P2的参数方程表示,如果能判断出线段进入多边形时候的参数ts和线段退出多边形时的参数te,则tste之间的线段为裁剪完毕后的结果。

4、判定线段上的点和多边形的关系

假定A为区域边界L上的任意一点,记L的内法向量(垂直)为N对于线段上任意一点 Pi, Pi和多边形边界L的关系有三种可能(t 为此点的参数值):

性质(1): 如果点P(t)在多边形所有边的内侧,则称P是在多边形的内侧。

可见线段的参数区间

5、编程思路

6、程序代码

double ts,te;
int Cyrus_Beck (int k,double A[][2],double N[][2],double x[2],double y[2],double *ts,double *te)
{
    int i,j;
    double t,dn,nw,D[2],W[2];
    *ts=0;
    *te=1;
    for(i=0; i<k; i++)
    {
        dn=N[i][0]*(x[1]- x[0])+N[i][1]* (y[1]-y[0]);
        nw=N[i][0]* (x[0]-A[i][0])+N[i][1]* (y[0]- A[i][1]);

        if(fabs(dn)<1.0e-6)  //平行
        {
            if(nw<0)
                return 0;    //p在L外侧
        }
        else
        {
            t=-nw/dn;
            if(dn<0)
            {
                if(t< *te)
                    *te=t;   //终点
            }
            else if(t> *ts)
                *ts=t;  //起点
        }
        if(*ts>*te)
            return 0; //在区域外
    }
    return 1;
}

三、梁友栋-Barsky算法

 当凸多边形是矩形窗口,且矩形的边平行于坐标轴时, Cyrus-Beck算法可简化为梁友栋-Barsky算法。

基本步骤

初始化线段在边界内的端点参数为ts=0、te=1。

计算出各个裁剪边界的r、s值。

当r=0且s<0时,舍弃该线段;否则计算线段与边界的交点参数t。
当r<0时,参数t用于更新ts;
当r>0时,参数t用于更新te。

如果更新了ts或te后,使ts>te,则舍弃该线段。

原文地址:https://www.cnblogs.com/wkfvawl/p/11704803.html

时间: 2024-08-24 23:32:39

计算机图形学——裁剪的相关文章

计算机图形学 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

计算机图形学名词解释

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

计算机图形学 复习笔记

计算机图形学 复习笔记 (个人整理,仅做复习用 :D,转载注明出处:http://blog.csdn.net/hcbbt/article/details/42779341) 第一章 计算机图形学综述 研究内容 图形的概念:计算机图形学的研究对象 能在人的视觉系统中产生视觉印象的客观对象 包括自然景物.拍摄到的图片.用数学方法描述的图形等等 图形的要素 几何要素:刻画对象的轮廓.形状等 非几何要素:刻画对象的颜色.材质等 图形表示法 点阵表示 枚举出图形中所有的点,简称为图像. 参数表示 由图形的

学习shader之前必须知道的东西之计算机图形学(一)渲染管线

引言 shader到底是干什么用的?shader的工作原理是什么? 其实当我们对这个问题还很懵懂的时候,就已经开始急不可耐的要四处搜寻有关shader的资料,恨不得立刻上手写一个出来.但看了一些资料甚至看了不少cg的语法之后,我们还是很迷茫,UNITY_MATRIX_MVP到底是个什么矩阵?它和v.vertex相乘出来的又是什么玩意?当这些问题困扰我们很久之后,我们才发现,原来我们是站在浮沙上筑高台,根基都没有打牢当然不可能盖得起高楼大厦了. 那根基是什么呢?大牛曰,计算机图形学. shader

计算机图形学研究领域分哪些

计算机图形学各个领域的目标或许不同,但最终的形式都是渲染(即绘制)在二维的显示设备上的图像.下面是一个简单(可能并不完全)的分类: ?计算机图形学-领域及分支: ?1 绘制1.1 真实感绘制(非实时)1.1.1 光线追踪(Ray-tracing)1.1.2 全局光照(Global Illumination)......1.2 实时绘制1.2.1 Shading(BRDF, Programmable Shading等)1.2.2 纹理(Texture Synthesis, 反走样, 采样等)1.2

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

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

计算机图形学和OpenGL(二)坐标系和绘制点线函数

这节开始前我们先了解一下图元的概念.图形软件包中用来描述各种图形元素的函数称为图形输出原语,也称图元(primitive).而描述对象几何要素的输出图元一般称为几何图元.点和线是最简单的几何图元,本节就会简单介绍点和线段的绘制方法. 一.坐标系统. 坐标系统一般分为屏幕坐标和OpenGL中的绘图坐标. 在上一节中我们简单的写了个示例程序,程序中介绍了gluOrtho2D命令.我们可以利用该命令设定一个二维笛卡尔坐标系.该函数的四个变量制定的是显示图形x和y坐标范围.所以我们可以使用下面代码制定一

计算机图形学的学习资源

计算机图形学(Computer Graphics,简称CG)是一个令人着迷的领域,本文整理了一些图形学相关的学习资源. Wikipedia的介绍,及其后面附的"参考文献"和"外部链接"总是值得一看的: Computer graphics:主要介绍图形学的历史: Computer graphics (computer science):介绍图形学学科,后面附了知名研究者,以及著名大学的图形学小组: 3D computer graphics:这是图形学中最重要的部分:

计算机图形学之光栅图形学——反走样算法简介

本文是对 赵明老师 <计算机图形学>MOOC课程 部分章节的小总结. 走样是数字化不可避免的. 简化: