Computer Graphics Chapter 5 Two-Dimensional Transformation and Cropping Completed

Midpoint segmentation straight line segment clipping algorithm

The midpoint segmentation straight line segment clipping algorithm improves the third case of the Cohen-Sutherland straight line clipping algorithm.

principle
Insert image description here

midpoint calculation formula

Insert image description here
Insert image description here

code

BOOL CTestView::Cohen()//Cohen-Sutherland算法
{
    
    
	EnCode(P[0]);//起点编码
	EnCode(P[1]);//终点编码
	while(P[0].rc!=0 || P[1].rc!=0)
             {
    
    //处理至少一个顶点在窗口之外的情况
		if((P[0].rc & P[1].rc)!=0)//简弃之
		{
    
    
			PtCount=0;
			return FALSE;
		}
		if(0==P[0].rc)//确保P[0]位于窗口之外
		{
    
    
			CP2 Temp;
			Temp=P[0];
			P[0]=P[1];
			P[1]=Temp;
		}
		MidClip(P[0],P[1]);
	}
	return TRUE;
}

void CTestView::MidClip(CP2 p0,CP2 p1)//中点分割算法
{
    
    
	CP2 p;//中点坐标	
	p.x=(p0.x+p1.x)/2;p.y=(p0.y+p1.y)/2;EnCode(p);
	while(fabs(p.x-p0.x)>1e-6||fabs(p.y-p0.y)>1e-6)//判断结束
	{
    
    
		if(0==p.rc)//中点也在窗口内,则舍弃P0点
		      p1=p;
		else//否则舍弃P1点
		       p0=p;
		p.x=(p0.x+p1.x)/2;
                       p.y=(p0.y+p1.y)/2;
                       EnCode(p);
	}
	P[0]=p;
}


Liang-Barsky straight line segment clipping algorithm⭐⭐⭐

In the early 1980s, Mr. Liang Youdong proposed the famous Liang-Barsky clipping algorithm, which achieves rapid clipping through the parametric representation of line segments. It is still one of the most classic algorithms in computer graphics.

Liang Youdong and Barsky proposed a straight line segment clipping algorithm that is faster than the Cohen-Sutherland clipping algorithm.

The main idea of ​​the beam algorithm must be described (test)

Principle:
This algorithm is designed based on the parametric equation of a straight line. It transforms the two-dimensional clipping problem of determining the intersection of a straight line and the window boundary into a one-dimensional clipping problem of solving a set of inequalities and determining the parameters of the straight line.
Insert image description here

When t=0 , it is the starting point; when t=1 , it is the end point.
Insert image description here

Cropping window:
Insert image description here

Insert image description here
Insert image description here
Insert image description here

This algorithm mainly examines changes in parameter t.
Insert image description here

Insert image description here
Insert image description here
Insert image description here
Insert image description here
Insert image description here

Insert image description here

The definition of parameter u is above. In the vertical case of the above figure, only two values ​​of n=3 and 4 need to be judged.

Insert image description here

Code:

void CTestView::LBLineClip()//Liang-Barsky裁剪函数
{
    
    
	double tmax,tmin,dx,dy;
	dx=P[1].x-P[0].x;dy=P[1].y-P[0].y;tmax=0.0,tmin=1.0;
	if(ClipTest(-dx,P[0].x-wxl,tmax,tmin)) //窗口边界的左、右、下、上顺序裁剪直线
	{
    
    
		if(ClipTest(dx,wxr-P[0].x,tmax,tmin))
		{
    
    			
			if(ClipTest(-dy,P[0].y-wyb,tmax,tmin))
			{
    
    
				if(ClipTest(dy,wyt-P[0].y,tmax,tmin))
				{
    
    
					if(tmin<1.0)//判断直线终点
					{
    
    
						      
                                                                                            P[1].x=P[0].x+tmin*dx;
						  
                                                                                            P[1].y=P[0].y+tmin*dy
					}
					if(tmax>0.0)//判断直线的起点
					{
    
    
						 
                                                                                          P[0].x=P[0].x+tmax*dx;
						
                                                                                          P[0].y=P[0].y+tmax*dy;
					}
                  									                                }
			}
		}
	}
}

BOOL CTestView::ClipTest(double u,double v,double &tmax,double &tmin)//裁剪测试函数
{
    
    
	double t;
	BOOL ReturnValue=TRUE;
	if(u<0.0)//从裁剪窗口的外部到内部,计算起点处的tmax
	{
    
    
		t=v/u;
		if(t>tmin)
			ReturnValue=FALSE;
		else if(t>tmax)
			tmax=t;
	}
	else
	{
    
    
		if(u>0.0)//从裁剪窗口的内部到外部,计算终点处的tmin
		{
    
    
			t=v/u;
			if(t<tmax)
				ReturnValue=FALSE;
			else if(t<tmin)
				tmin=t;
		}
		else//平行于窗口边界的直线
		{
    
    
			if(v<0.0)//直线在窗口外可直接删除
				ReturnValue=FALSE;
		}
	}
	return(ReturnValue);
}



Polygon clipping algorithm/Sutherland-Hodgman clipping algorithm

The Sutherland-Hodgman clipping algorithm is also called the edge-by-edge clipping algorithm. The basic idea is to use the four edges of the clipping window to clip polygons in sequence.
The order in which the window borders are clipped does not matter; here the order of left, right, bottom, and top is used.
The output result of the polygon clipping algorithm is the clipped polygon vertex sequence .
Insert image description here

Insert image description here

Insert image description here

Insert image description here

  • In order to correctly clip a concave polygon, one method is to first split the concave polygon into two or more convex polygons, and then clip them separately using the Sutherland-Hodgman clipping algorithm.
  • Another method is to use the Weiler-Atherton clipping algorithm . This algorithm is suitable for any convex or concave polygon clipping with inner holes, but the calculation workload is very large.

code

void CTestView::ClipPolygon(CP2 *out,int Length,UINT Boundary)
{
    
    
	CP2 *pTemp=new CP2[Length];
	for(int i=0;i<Length;i++)
		pTemp[i]=out[i];
	CP2 p0,p1,p;//p0-起点,p1-终点,p-交点
	OutCount=0;
	p0=pTemp[Length-1];
	for(i=0;i<Length;i++)
	{
    
    
		p1=pTemp[i];
		if(Inside(p0,Boundary))//起点在窗口内
		{
    
    
			if(Inside(p1,Boundary))//终点在窗口内,属于内→内
			{
    
    
				Out[OutCount]=p1;//终点在窗口内
				OutCount++;
			}
			else//属于内→外
			{
    
    
				p=Intersect(p0,p1,Boundary);//求交点
				Out[OutCount]=p;
				OutCount++;
			}
		}
		
	else if(Inside(p1,Boundary))//终点在窗口内,属于外→内
		{
    
    
			p=Intersect(p0,p1,Boundary);//求交点
			Out[OutCount]=p;
			OutCount++;
			Out[OutCount]=p1;
			OutCount++;
		}
		p0=p1;
	}
	delete[] pTemp;
}

This chapter gives three straight line segment clipping algorithms, among which the Cohen-Sutherland clipping algorithm is the most famous. It innovatively proposes the coding rules for the end points of the straight line segment. However, this clipping algorithm needs to calculate the intersection point of the straight line segment and the window; the midpoint The segmentation and clipping algorithm avoids solving the intersection point of the straight line segment and the window boundary. It only needs to calculate the coordinates of the midpoint of the straight line segment to complete the cutting of the straight line segment, but the iterative calculation workload is large.

The Liang-Barsky clipping algorithm is the most efficient algorithm among the three algorithms. By calculating the parameter t, the two-dimensional clipping problem is converted into a one-dimensional clipping problem, and the clipping of straight line segments is converted into a problem of solving a set of inequalities. Two-dimensional cropping belongs to the content of two-dimensional observation. The window is established in the observation coordinate system, and the viewport is established in the screen coordinate system. In order to reduce the calculation amount of window transformation, this textbook assumes that the size of the window and the viewport are the same.

Related learning materials:

[Case 20-Liang-Barsky algorithm]

Guess you like

Origin blog.csdn.net/CSDN_YJX/article/details/128803927