📅  最后修改于: 2020-12-21 00:44:29             🧑  作者: Mango
它是通过使用行剪切算法来执行的。剪线算法为:
在该算法中,首先,检测线是位于屏幕内部还是位于屏幕外部。所有行都属于以下任一类别:
1.可见:如果一条线位于窗口内,即该线的两个端点都位于窗口内。一条线可见,将按原样显示。
2.不可见:如果一条线位于窗口外部,则将不可见并被拒绝。这样的行将不会显示。如果满足以下任一不等式,则该行被视为不可见。令A(x 1 ,y 2 )和B(x 2 ,y 2 )是直线的端点。
x min ,x max是窗口的坐标。
y min ,y max也是窗口的坐标。
x 1 > x最大
x 2 > x最大
y 1 > y最大值
y 2 > y最大值
x 1
x 2
y 1
y 2
3.剪切大小写:如果行既不是可见大小写也不是不可见大小写。它被认为是裁剪的情况。首先,根据以下九个区域找到线的类别。所有九个区域均分配有代码。每个代码为4位。如果该行的两个端点的结束位均为零,则该行被视为可见。
中心区域的代码为0000,即区域5被视为矩形窗口。
下图显示了各种类型的行
AB行是可见的情况
op线是不可见的情况
pq线是不可见的线
ij线是剪裁候选人
mn行是剪切候选
线cd是剪切候选< p="">
步骤1:计算线的两个端点的位置
步骤2:在这两个端点上执行“或”运算
第三步:如果“或”运算得到0000
然后
线被认为是可见的
其他
在两个端点上执行AND操作
如果And≠0000
那么这条线是不可见的
其他
和= 0000
线被认为是剪裁的情况。
步骤4:如果线被剪裁,则找到与窗口边界的交点
m =(y 2 -y 1 )(x 2 -x 1 )
(a)如果位1为“ 1”,则线与矩形窗口的左边界相交
y 3 = y 1 + m(xX 1 )
其中X = X wmin
其中X wmin是窗口的X坐标的最小值
(b)如果位2为“ 1”,则线与右边界相交
y 3 = y 1 + m(XX 1 )
其中X = X wmax
其中X more是窗口的X坐标的最大值
(c)如果位3为“ 1”,则线与底部边界相交
X 3 = X 1 +(yy 1 )/ m
其中y = y wmin
y wmin是窗口的Y坐标的最小值
(d)如果位4为“ 1”,则线与顶边界相交
X 3 = X 1+(yy 1 )/ m
其中y = y wmax
y wmax是窗口的Y坐标的最大值
令R为矩形窗口,其左下角为L(-3,1),右上角为R(2,6)。在图中找到端点的区域代码:
根据方案设置点(x,y)的区域代码
位1 =符号(yy max )=符号(y-6)位3 =符号(xx max )=符号(x-2)
位2 =符号(y min -y)=符号(1-y)位4 =符号(x min -x)=符号(-3-x)
这里
所以
A(-4,2)→0001 F(1,2)→0000
b(-1,7)→1000="" c(-1,5)→0000="" d(3,8)→1010="" e(-2,3)→0000="" g(1,-2)→0100
="" h(3,3)→0100
="" i(-4,7)→1001
="" j(-2,10)→1000<="" p="">
通过测试问题中发现的区域代码,我们将线段放在适当的类别中。
Category1(可见): EF,因为两个端点的区域代码均为0000。
Category2(不可见):因为(1001)AND(1000)= 1000(不是0000),所以IJ。
类别3(剪辑对象): AB (0001)AND(1000)= 0000, CD (0000)AND(1010)= 0000, GH。因为(0100)AND(0010)= 0000。
裁剪的候选对象是AB, CD和GH。
在裁剪AB时,A的代码为0001。要将1推为0,我们将裁剪边界线x min = -3。所得的交点为I 1 (-3,3 )。我们剪辑(不显示)AI 1和I 1 B的代码为I 1是1001的修剪类别I 1个B是3,因为(0000)和(1000)是(0000)。现在,B在窗口之外(即,其代码为1000),因此我们将y max = 6剪掉,将1推到0。所得的交点为l 2 (-1 ,6)。因此, I 2 B被削波。 I 2的代码为0000。由于两个端点都位于窗口中(即,它们的代码为0000),因此显示了剩余的段I 1 I 2。
对于剪辑CD ,我们从D开始,因为它在窗口之外。它的代码是1010。我们将y max = 6剪掉,将第一个1推到0。所得的交点I 3为( ,6),其代码为0000。因此I 3 D被剪切,其余段CI 3的两个端点都被编码为0000,因此将其显示。
对于剪切GH ,我们可以从G或H开始,因为两者都在窗口之外。 G的代码是0100,我们通过截断y min = 1的线将1推到0,得到的交点是I 4 (2 ,1)和它的代码是0010。我们在I剪辑GI 4和工作我4小时,因为(0010上不显示4 H.段)AND(0010)= 0010。
#include
#include
#include
#include
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<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 ();
}
输出:
>op线是不可见的情况