欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪

程序员文章站 2022-07-14 10:00:40
...

(1)算法设计原理
依次处理(p1,q1)(p2,q2)(p3,q3)(p4,q4)四组数据:把(pk,qk)作为ClipT函数的输入变量
p1=p2=0时,若q1<0或q2小于0,直线在窗口外
P3=p4=0时,若q3<0或q4小于0,直线在窗口外
那么,pk=0并且qk<0时,不画线,设成返回false;

p1=p2=0时,若q1>=0且q2>=0,计算uk|pk<0,和umax比较大小成为新的umax,计算 uk|pk>0,和umin比较大小成为新的umin,k=3,4
P3=p4=0时,若q3>=0且q4>=0,计算uk|pk<0,和umax比较大小成为新的umax,计算 uk|pk>0,和umin比较大小成为新的umin,k=1,2

P1!=p2时,计算uk|pk<0,和umax比较大小成为新的umax,计算 uk|pk>0,和umin比较大小成为新的umin,k=1,2,3,4

在Clip函数中,pk<0,则计算相应的uk|pk<0,并和umax比较;
pk>0,计算相应的uk|pk>0,并和umin比较;
剩下pk=0的情况,qk<0,直线在窗口外;返回false
qk>0,不需要进行操作;
k分别等于1,2,3,4后,所有直线在窗口外的情况都返回了false,并得到了umax,umin。
(2)程序关键代码
计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪
计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪
(3)运行结果截屏(对数据输入的说明)
计算机图形学-3.2用Liang-Barsky算法实现直线段裁剪
完整代码:

#define xl 150
#define xr 300
#define yb 150
#define yt 300
#include <stdio.h>
#include <graphics.h>
#include <math.h>
#include<conio.h>

//当线段完全不可见时,返回false,否则,返回true
bool ClipT(double p,double q,double &t0,double &t1)
{
	double r;
	if(p<0)
	{
		r=(double)q/(double)p;
		if(r>t1)
			return false;
		else if (r>t0)
		{
			t0=r;
			return true;
		}
	}
	else if (p>0)
	{
		r=(double)q/(double)p;
		if(r<t0)
			return false;
		else if(r<t1)
		{
			t1=r;
			return true;
		}
	}
	else if(q<0)
		return false;
	return true;
}

void L_B_line(double x1,double y1,double x2,double y2)
{
	double dx,dy,umin,umax;
	umin=0;umax=1;
	dx=x2-x1;
	                                       //若x1,x2相同,p1=p2=0,q1<0,则直线不在窗口内,返回false,结束
										   //x1,x2相同,umin=0,umax=1
	                                       //x1,x2不同情况下,计算uk|pk<0,和umax比较大小成为新的umax,计算 uk|pk>0,和umin比较大小成为新的umin
	if(ClipT(-dx,x1-xl,umin,umax)) 
                                          	//若x1,x2相同,p1=p2=0,q2<0,则直线不在窗口内,返回false,结束
											//x1,x2相同,umin不变,umax不变
                                            //x1,x2不同情况下,计算uk|pk<0,和umax比较大小成为新的umax,计算 uk|pk>0,和umin比较大小成为新的umin
		if(ClipT(dx,xr-x1,umin,umax))
		{
			dy=y2-y1;
		                                 	//若y1,y2相同,p3=p4=0,q3<0,则直线不在窗口内,返回false,结束
			                                //y1,y2相同,umin不变,umax不变
			                                //计算y1,y2不同情况下,计算uk|pk<0,和umax比较大小成为新的umax,计算 uk|pk>0,和umin比较大小成为新的umin
			if(ClipT(-dy,y1-yb,umin,umax))    
				                             //若y1,y2相同,p3=p4=0,q4<0,则直线不在窗口内,返回false,结束
											 //x1,x2相同,umin不变,umax不变
			                                 //计算y1,y2不同情况下,计算uk|pk<0,和umax比较大小成为新的umax,计算 uk|pk>0,和umin比较大小成为新的umin
				if(ClipT(dy,yt-y1,umin,umax))   
					                            
					line((int)(x1+umin*dx),(int)(y1+umin*dy),(int)(x1+umax*dx),(int)(y1+umax*dy));
		}
}
void main()
{
	initgraph(640,480);
	setlinecolor(WHITE);
	line(xl,yt,xr,yt);
	line(xl,yb,xr,yb);
	line(xl,yt,xl,yb);
	line(xr,yt,xr,yb);
	double x0,y0,x1,y1;
	//用鼠标获取点的位置
	MOUSEMSG m;
	while(true)
	{flag:
		m=GetMouseMsg();//获取一次鼠标消息
		switch(m.uMsg)
		{
		case WM_LBUTTONDOWN:
			x0=m.x;y0=m.y;
			setcolor(RED);
			circle((int)x0,(int)y0,2);
			while(true)
			{
				m=GetMouseMsg();//再获取一次鼠标消息
				switch(m.uMsg)
				{
				case WM_LBUTTONDOWN:
					x1=m.x;y1=m.y;
					circle((int)x1,(int)y1,2);
						setcolor(RED);
					line((int)x0, (int)y0, (int)x1, (int)y1);
					setcolor(YELLOW);
					L_B_line((int)x0,(int)y0,(int)x1,(int)y1);
					goto flag;
				}
			}
		}
	}

   	_getch();
	closegraph();
}
相关标签: 计算机图形学