个性化阅读
专注于IT技术分析

计算机图形剪线算法

本文概述

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

  1. Cohen Sutherland线截断算法
  2. 中点细分线剪切算法
  3. Liang-Barsky剪线算法

Cohen Sutherland线截断算法

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

  1. 可见
  2. 不可见
  3. 裁剪盒

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. 它可以剪辑比屏幕大得多的图片。

科恩·萨瑟兰剪线算法

步骤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 ();
    }

输出:

剪线算法

赞(0)
未经允许不得转载:srcmini » 计算机图形剪线算法

评论 抢沙发

评论前必须登录!