opengl 图形学3个直线裁剪算法

图形学三个最基础的直线裁剪算法

//根据x、y来编码
int EnCode(int x,int y){

	int c = 0;

	if (x<XL)
	{
		c |= LEFT;
	}
	if (x>XR)
	{
		c |= RIGHT;
	}
	if (y>YT)
	{
		c |= TOP;
	}
	if (y<YB)
	{
		c |= BOTTOM;
	}
    
	return c;
}

//Cohen-Sutherland裁剪算法
void CS_LineClip(int idex,int XL,int YB,int XR,int YT) {
	int x1 = gdLDArr[idex].x0;
	int x2 = gdLDArr[idex].x1;
	int y1 = gdLDArr[idex].y0;
	int y2 = gdLDArr[idex].y1;

	
	int code1,code2,code,x,y;
	code1 = EnCode(x1,y1);
	code2 = EnCode(x2,y2);

	while (code1!=0||code2!=0)
	{
		if ((code1&code2) != 0) { 
			gdLDArr[idex].x0 = 0;
			gdLDArr[idex].y0 = 0;
			gdLDArr[idex].x1 = 0;
			gdLDArr[idex].y1 = 0;

			return; 
		}

		if (code1 != 0) { code = code1; x = x1; y = y1; }
		else { code = code2; x = x2; y = y2;}

		if ((LEFT&code)!=0)
		{
			x = XL;
			y = y1 + (y2 - y1)*(XL - x1) / (x2 - x1);
		}
		else if ((RIGHT&code)!=0)
		{
			x = XR;
			y = y1 + (y2 - y1)*(XR - x1) / (x2 - x1);
		}
		else if ((BOTTOM&code) != 0)
		{
			y = YB;
			x = x1 + (x2 - x1)*(YB - y1) / (y2 - y1);
		}
		else if ((TOP&code) != 0)
		{
			y = YT;
			x = x1 + (x2 - x1)*(YT - y1) / (y2 - y1);
		}
		
		if (code==code1)
		{
			x1 = x; y1 = y; code1 = EnCode(x, y);
		}
		else
		{
			x2 = x; y2 = y; code2 = EnCode(x, y);
		}
		
	}

	gdLDArr[idex].x0 = x1;
	gdLDArr[idex].x1 = x2;
	gdLDArr[idex].y0 = y1;
	gdLDArr[idex].y1 = y2;
}

//中点裁剪算法
void MP_LineClip(int idex, int XL, int YB, int XR, int YT) {
	int x1 = gdLDArr[idex].x0;
	int x2 = gdLDArr[idex].x1;
	int y1 = gdLDArr[idex].y0;
	int y2 = gdLDArr[idex].y1;


	int code1, code2, code,xm, ym,xl,xr,yl,yr;
	code1 = EnCode(x1, y1);
	code2 = EnCode(x2, y2);

	while (code1 != 0 || code2 != 0)
	{
		if ((code1&code2) != 0) {
			gdLDArr[idex].x0 = 0;
			gdLDArr[idex].y0 = 0;
			gdLDArr[idex].x1 = 0;
			gdLDArr[idex].y1 = 0;

			return;
		}

		if (code1 != 0) { code = code1;}
		else { code = code2;}

		if ((LEFT&code) != 0)
		{
			xl = x1 < x2 ? x1 : x2;
			xr = x1 < x2 ? x2 : x1;
			yl = xl == x1 ? y1 : y2;
			yr = xl == x1 ? y2 : y1;
			xm = (xl + xr) / 2;
			ym = (yl + yr) / 2;

			while (xm!=XL)
			{
				if (xm<XL)
				{
					xl = xm;
					yl = ym;
				}
				else
				{
					xr = xm;
					yr = ym;
				}
				xm = (xl + xr) / 2;
				ym = (yl + yr) / 2;
			}
		}
		else if ((RIGHT&code) != 0)
		{
			xl = x1 < x2 ? x1 : x2;
			xr = x1 < x2 ? x2 : x1;
			yl = xl == x1 ? y1 : y2;
			yr = xl == x1 ? y2 : y1;
			xm = (xl + xr) / 2;
			ym = (yl + yr) / 2;

			while (xm != XR)
			{
				if (xm<XR)
				{
					xl = xm;
					yl = ym;
				}
				else
				{
					xr = xm;
					yr = ym;
				}
				xm = (xl + xr) / 2;
				ym = (yl + yr) / 2;
			}
		}
		else if ((BOTTOM&code) != 0)
		{
			yl = y1 < y2 ? y1 : y2;
			yr = y1 < y2 ? y2 : y1;
			xl = yl == y1 ? x1 : x2;
			xr = yl == y1 ? x2 : x1;
			xm = (xl + xr) / 2;
			ym = (yl + yr) / 2;

			while (ym != YB)
			{
				if (ym<YB)
				{
					yl = ym;
					xl = xm;
				}
				else
				{
					yr = ym;
					xr = xm;
				}
				xm = (xl + xr) / 2;
				ym = (yl + yr) / 2;
			}
		}
		else if ((TOP&code) != 0)
		{
			yl = y1 < y2 ? y1 : y2;
			yr = y1 < y2 ? y2 : y1;
			xl = yl == y1 ? x1 : x2;
			xr = yl == y1 ? x2 : x1;
			xm = (xl + xr) / 2;
			ym = (yl + yr) / 2;

			while (ym != YT)
			{
				if (ym<YT)
				{
					yl = ym;
					xl = xm;
				}
				else
				{
					yr = ym;
					xr = xm;
				}
				xm = (xl + xr) / 2;
				ym = (yl + yr) / 2;
			}
		}

		if (code == code1)
		{
			x1 = xm; y1 = ym; code1 = EnCode(x1, y1);
		}
		else
		{
			x2 = xm; y2 = ym; code2 = EnCode(x2, y2);
		}

	}

	gdLDArr[idex].x0 = x1;
	gdLDArr[idex].x1 = x2;
	gdLDArr[idex].y0 = y1;
	gdLDArr[idex].y1 = y2;
}

bool ClipT(float p, float q, float *u1, float *u2) {
	float r;
	if (p<0)
	{
		r = q / p;
		if (r>*u2)
		{
			return false;
		}

		if (r > *u1) {
			*u1 = r;
		}
	}
	else if (q>0)
	{
		r = q / p;
		if (r<*u1)
		{
			return false;
		}
		if (r<*u2)
		{
			*u2 = r;
		}
	}
	else {
		return (q >= 0);
	}
	return true;
}


//Liang-Barskey裁剪算法
void LB_LineClip(int idex, int XL, int YB, int XR, int YT) {
	int x1, x2, y1, y2;
	x1 = gdLDArr[idex].x0;
	x2 = gdLDArr[idex].x1;
	y1 = gdLDArr[idex].y0;
	y2 = gdLDArr[idex].y1;

	float dx, dy, u1, u2;
	u1 = 0;
	u2 = 1;
	dx = x2 - x1;
	dy = y2 - y1;

	if (ClipT(-dx,x1-XL,&u1,&u2))
		if (ClipT(dx, XR - x1, &u1, &u2))
			if (ClipT(-dy, y1 - YB, &u1, &u2))
				if (ClipT(dy, YT - y1, &u1, &u2)) {
					gdLDArr[idex].x0 = x1 + u1 * dx;
					gdLDArr[idex].y0 = y1 + u1 * dy;
					gdLDArr[idex].x1 = x1 + u2 * dx;
					gdLDArr[idex].y1 = y1 + u2 * dy;
					return;
				}
	
	gdLDArr[idex].x0 = 0;
	gdLDArr[idex].y0 = 0;
	gdLDArr[idex].x1 = 0;
	gdLDArr[idex].y1 = 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34131399/article/details/80330690