POJ1269 计算几何直线与直线的关系

题意:判断直线关系:共线,平行,交点

外积判断共线

模板代码如下:

#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
       
       
typedef long long int ll;
using   namespace    std;
const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x)
{
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}
struct point
{
	double x,y;
	point() {}  point(double _x,double _y)
	{
		x = _x;
		y = _y;
	}  point operator -(const point &b)const
	{
		return point(x - b.x,y - b.y);

	}
	double operator ^(const point &b)const	//叉积
	{
		return x*b.y - y*b.x;
	}
	double operator *(const point &b)const //点积
	{
		return x*b.x + y*b.y;     //绕原点旋转角度B(弧度值),后x,y的变化
	}
	void transXY(double B)
	{
		double tx = x,ty = y;
		x = tx*cos(B) - ty*sin(B);
		y = tx*sin(B) + ty*cos(B);
	}
};
struct line
{
	point s,e;
	line() {}
	line(point _s,point _e)
	{
		s = _s;
		e = _e;
	}
} lines[1005];
double xmult(point p0,point p1,point p2) //计算p0p1 X p0p2
{
	return (p1-p0)^(p2-p0);
}
bool isbanana(point s1,point e1,point s2,point e2) //判断线段P1P2 与线段P3P4是否相交
{
	return ( (max(s1.x,e1.x)+eps>min(s2.x,e2.x))&&
	         (max(s2.x,e2.x)+eps>min(s1.x,e1.x))&&
	         (max(s1.y,e1.y)+eps>min(s2.y,e2.y))&&
	         (max(s2.y,e2.y)+eps>min(s1.y,e1.y))&&
	         (xmult(s1,s2,e1)*xmult(s1,e1,e2)+eps>0)&&(xmult(s2,s1,e2)*xmult(s2,e2,e1)+eps>0) );
}
int linetoline(point p1,point p2,point p3,point p4)//判断线段P1P2与线段P3P4的关系
{
	if(sgn(xmult(p1,p3,p4))==0&&sgn(xmult(p2,p3,p4))==0)
	{
		return -2;//说明共线,共线不一定有交点  //PS 这种忽略了一种 共线但是没交点的情况
	}
	if(sgn((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x))==0)//说明平行
	{
		return -1;
	}
	if(!isbanana(p1,p2,p3,p4))//无交点 
	{
		return 0;
	}
	return 1;
}
point bananapoint(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
//返回直线p1p2 直线p3p4的交点 如果是直线就先判线段关系
{
	point res=point(0.0,0.0);
	double a1=y1-y2,b1=x2-x1,c1=x1*y2-x2*y1;
	double a2=y3-y4,b2=x4-x3,c2=x3*y4-x4*y3;
	double x=(c2*b1-c1*b2)/(b2*a1-b1*a2);
	double y=(a2*c1-a1*c2)/(b2*a1-b1*a2);
	if(y==0)y=fabs(y);
	if(x==0)x=fabs(x);
	res.x=x;
	res.y=y;
	return res;
}
int main()
{
	int T;
	cout<<"INTERSECTING LINES OUTPUT"<
       
       
         >T; while(T--) { double x1,y1,x2,y2,x3,y3,x4,y4; cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4; point p1=point(x1,y1); point p2=point(x2,y2); point p3=point(x3,y3); point p4=point(x4,y4); int ans=linetoline(p1,p2,p3,p4); if(ans==-2) { printf("LINE\n"); continue; } if(ans==-1) { printf("NONE\n"); continue; } // if(ans==0) // { // printf("NONE\n"); // continue; // } point pans=bananapoint(p1.x,p1.y,p2.x,p2.y,p3.x,p3.y,p4.x,p4.y); printf("POINT %.2f %.2f\n",pans.x,pans.y);//C++ 用%.2lf } cout<<"END OF OUTPUT"< 
         
       
      
      
     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值