本文概述
它是通过使用行剪切算法来执行的。剪线算法为:
- Cohen Sutherland线截断算法
- 中点细分线剪切算法
- Liang-Barsky剪线算法
Cohen Sutherland线截断算法
在该算法中, 首先, 检测线是位于屏幕内部还是位于屏幕外部。所有行都属于以下任一类别:
- 可见
- 不可见
- 裁剪盒
1.可见:如果一条线位于窗口内, 即该线的两个端点都位于窗口内。一条线可见, 将按原样显示。
2.不可见:如果一条线位于窗口外部, 则将不可见并被拒绝。这样的行将不会显示。如果满足以下任一不等式, 则该行被视为不可见。设A(x1, y2)和B(x2, y2)是直线的端点。
xmin, xmax是窗口的坐标。
ymin, ymax也是窗口的坐标。 x1> xmax x2> xmax y1> ymax y2> ymax x1 <xmin x2 <xmin y1 <ymin y2 <ymin
3.剪切大小写:如果行既不是可见大小写也不是不可见大小写。它被认为是裁剪的情况。首先, 根据以下九个区域找到线的类别。所有九个区域均分配有代码。每个代码为4位。如果该行的两个端点的结束位均为零, 则该行被视为可见。
中心区域的代码为0000, 即区域5被视为矩形窗口。
下图显示了各种类型的行
线AB是可见情况线OP是不可见情况线PQ是不可见线线IJ是剪切候选者线MN是剪切候选者线CD是剪切候选者
科恩·萨瑟兰剪线的优势
- 它可以非常快速地计算出端点, 并快速拒绝和接受线。
- 它可以剪辑比屏幕大得多的图片。
科恩·萨瑟兰剪线算法
步骤1:计算线的两个端点的位置
步骤2:在这两个端点上执行OR操作
步骤3:如果OR操作给出0000, 则认为该行可见, 否则在两个端点上执行AND操作如果And≠0000, 则该行不可见, 否则And = 0000该行被认为是修剪的情况。
步骤4:如果有线被剪裁的情况, 则找到与窗口边界相交的交点m =(y2-y1)(x2-x1)
(a)如果位1为“ 1”, 则直线与矩形窗口的左边界相交y3 = y1 + m(x-X1)其中X = Xwmin其中Xwminis窗口X坐标的最小值
(b)如果位2为“ 1”, 则线与右边界y3 = y1 + m(X-X1)相交, 其中X = Xwmax, 其中X more是窗口的X坐标的最大值
(c)如果位3为“ 1”, 则线与下边界X3 = X1 +(y-y1)/ m相交, 其中y = ywmin ywmin是窗口的Y坐标的最小值
(d)如果位4为“ 1”, 则线与顶边界X3 = X1 +(y-y1)/ m相交, 其中y = ywmax ywmax是窗口的Y坐标的最大值
Cohen-Sutherland裁线算法示例
令R为矩形窗口, 其左下角为L(-3, 1), 右上角为R(2, 6)。在图中找到端点的区域代码:
根据方案设置点(x, y)的区域代码位1 =符号(y-ymax)=符号(y-6)位3 =符号(x-xmax)=符号(x-2)位2 =符号(ymin-y)=符号(1-y)位4 =符号(xmin-x)=符号(-3-x)
这里
所以
A(-4, 2)→0001 F(1, 2)→0000 B(-1, 7)→1000 G(1, -2)→0100 C(-1, 5)→0000 H(3, 3) →0100 D(3, 8)→1010 I(-4, 7)→1001 E(-2, 3)→0000 J(-2, 10)→1000
通过测试问题中发现的区域代码, 我们将线段放在适当的类别中。
Category1(可见):EF, 因为两个端点的区域代码均为0000。
Category2(不可见):因为(1001)AND(1000)= 1000(不是0000), 所以IJ。
类别3(剪辑的候选者):AB(自(0001)和(1000)= 0000, CD自(0000)AND(1010)= 0000, GH)。因为(0100)AND(0010)= 0000。
剪切的候选对象是AB, CD和GH。
在裁剪AB中, A的代码为0001。为了将1推为0, 我们裁剪边界线xmin = -3。所得的交点为I1(-3, 3)。我们裁剪(不显示)AI1和I1B。I1的代码为1001。由于(0000)AND(1000)为(0000), 因此I1 B的裁剪类别为3。现在B在窗口之外(即, 其代码为1000), 因此我们将ymax = 6剪裁, 将1推为0。所得的交点为l2(-1, 6)。因此, I2 B被削波。 I2的代码是0000。由于两个端点都在窗口中(即, 它们的代码是0000), 所以会显示剩余的段I1 I2。
对于剪辑CD, 我们从D开始, 因为它在窗口之外。它的代码是1010。我们将ymax = 6剪掉, 将第一个1推到0。所得的交点I3为(, 6), 其代码为0000。因此, I3 D被裁剪, 其余段CI3的两个端点均被编码为0000, 因此将其显示。
对于剪切GH, 我们可以从G或H开始, 因为两者都在窗口之外。 G的代码是0100, 我们通过剪裁ymin = 1来将1推到0。得到的交点是I4(2, 1), 其代码是0010。我们剪裁GI4并在I4 H上工作。由于(0010)AND(0010)= 0010, 因此不显示段I4 H.
使用Cohen Sutherland算法执行剪线的程序:
#include <iostream.h>
#include <conio.h>
#include <graphics.h>
#include <dos.h>
class data
{
int gd, gmode, x, y, xmin, ymin, ymax, xmax;
int a1, a2;
float x1, y1, x2, y2, x3, y3;
int xs, ys, xe, ye;
float maxx, maxy;
public:
void getdata ();
void find ();
void clip ();
void display (float, float, float, float);
void checkonof (int);
void showbit (int);
};
void data :: getdata ()
{
cout<<"Enter the minimum and maximum coordinate of window (x, y) ";
cin >>xmin>>ymin>>xmax>>ymax;
cout<<"Enter the end points of the line to be clipped";
cin >>xs>>ys>>xe>>ye;
display (xs, ys, xe, ye);
}
void data :: display (float, xs, float, ys, float xe, float ye)
{
int gd=DETECT;
initgraph (&gd, &gmode, "");
maxx=getmaxx();
maxy=getmaxy();
line (maxx/2, 0, maxx/2, maxy);
line (0, maxy/2, maxx, maxy/2);
rectangle (maxx/2+xmin, maxy/2-ymax, maxx/2+xmax, maxy/2-ymin);
line (maxx/2+xs, maxy/2-ys, maxx/2+xe, maxy/2-ye);
getch();
}
void data :: find ()
{
a1=0;
a2=0;
if ((ys-ymax)>0)
a1+=8;
if ((ymin-ys)>0)
a1+=4;
if ((xs-xmax)>0)
a1+=2;
if ((xmin-xs)>0)
a1+=1;
if ((ye-ymax)>0)
a2+=8;
if ((ymin-ye)>0)
a2+=4;
if ((xe-xmax)>0)
a2+=2;
if ((xmin-xe)>0)
a2+=1;
cout<<"\nThe area code of Ist point is ";
showbit (a1);
getch ();
cout <<"\nThe area code of 2nd point is ";
showbit (a2);
getch ();
}
void data :: showbit (int n)
{
int i, k, and;
for (i=3;i>=0;i--)
{
and =1<<i;
k = n?
k ==0?cout<<"0": cout<<"1\"";
}
}
void data ::clip()
{
int j=a1&a2;
if (j==0)
{
cout<<"\nLine is perfect candidate for clipping";
if (a1==0)
{
else
{
checkonof(a1);
x2=x1;y2=y1;
}
if (a2=0)
{
x3=xe; y3=ye;
}
else
{
checkonof (a2);
x3=x1; y3=y1;
}
xs=x2; ys=y2;xe=x3;ye=y3;
cout << endl;
display (xs, ys, xe, ye);
cout<<"Line after clipping";
getch ()
}
else if ((a1==0) && (a2=0))
{
cout <<"\n Line is in the visible region";
getch ();
}
}
void data :: checkonof (int i)
{
int j, k, l, m;
1=i&1;
x1=0;y1=0;
if (1==1)
{
x1=xmin;
y1=ys+ ((x1-xs)/ (xe-xs))*(ye-ys);
}
j=i&8;
if (j>0)
{
y1=ymax;
x1=xs+(y1-ys)/(ye-ys))*(xe-xs);
}
k=i & 4;
if (k==1)
{
y1=ymin;
x1=xs+((y1-ys)/(ye-ys))*(xe-xs);
}
m= i&2;
if (m==1)
{
x1=xmax;
y1=ys+ ((x1-xs)/ (xe-xs))*(ye-ys);
}
main ()
{
data s;
clrscr();
s.getdata();
s.find();
getch();
closegraph ();
return ();
}
输出:
评论前必须登录!
注册