📜  计算机图形学|换行

📅  最后修改于: 2020-12-21 00:44:29             🧑  作者: Mango

剪线:

它是通过使用行剪切算法来执行的。剪线算法为:

  • Cohen Sutherland裁线算法
  • 中点细分线剪切算法
  • Liang-Barsky裁剪线算法

科恩·萨瑟兰(Cohen Sutherland)剪线算法:

在该算法中,首先,检测线是位于屏幕内部还是位于屏幕外部。所有行都属于以下任一类别:

  • 可见
  • 不可见的
  • 裁剪盒

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, CDGH。

在裁剪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。

使用Cohen Sutherland算法执行剪线的程序:

#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线是不可见的情况
pq线是不可见的线
ij线是剪裁候选人
mn行是剪切候选
线cd是剪切候选<>