您的位置:首页 > 其它

uva191 Intersection(线段之间相交)

2016-05-10 10:05 405 查看
题意:是否线段与矩形相交,线段在矩形内部也是相交。

公式:p1*p2=(x1*x2,y1*y2)(内积),p1xp2=(x1*y2,x2*y1)(外积)

判断q是否在线段p1-p2上面,根据(p1-q)x(p2-q)=0来判断q是否在直线p1-p2上。利用内积(p1-q)*(p2-q)<0判断q是否在p1-p2之间。

p1-p2,q1-q2的交点:

(x,y)=p1+(p2-p1)*((q2-q1)x(q1-p1)/((q2-q1)x(p2-p1)));

注意:左顶点和右下角的坐标输入,不是按照先左上角然后右下角这个顺序输入的,总之你需要判断得出左上角和右下角的坐标。

#include <iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define EPS 1e-10

struct point
{
double a,b;
point(){}
point(double a,double b):a(a),b(b){}
point operator +(point p)
{
return point(p.a+a,p.b+b);
}
point operator -(point p)
{
return point(a-p.a,b-p.b);
}
point operator *(double p)
{
return point(a*p,b*p);
}
double dot(point p)//内积
{
return (p.a*a+p.b*b);
}
double det(point p)//外积
{
return (a*p.b-b*p.a);
}
};
point p1,p2,q1,q2;
//判断q是否在线段p1-p2上
bool on_str(point p1,point p2,point q)
{
return (abs((p1-q).det(p2-q))<EPS&&(p1-q).dot(p2-q)<EPS);
}
//求两直线交点
point intersection(point p1,point p2,point q1,point q2)
{
return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
}
bool judge(point q1,point q2)
{
if(abs((p1-p2).det(q1-q2))<EPS)
{
if(on_str(p1,p2,q1)||on_str(p1,p2,q2)||on_str(q1,q2,p1)||on_str(q1,q2,p2))//判断是否有重合
return 1;
else
return 0;
}
point r=intersection(p1,p2,q1,q2);
return on_str(p1,p2,r)&&on_str(q1,q2,r);
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p1.a,&p1.b,&p2.a,&p2.b,&q1.a,&q1.b,&q2.a,&q2.b);
if(q1.a>q2.a)
swap(q1.a,q2.a);
if(q1.b<q2.b)
swap(q1.b,q2.b);
if(p1.a>=q1.a&&p1.a<=q2.a&&p1.b<=q1.b&&p1.b>=q2.b&&p2.a>=q1.a&&p2.a<=q2.a&&p2.b<=q1.b&&p2.b>=q2.b)
{
printf("T\n");
}
else{
if(judge(q1,point(q2.a,q1.b))||judge(q1,point(q1.a,q2.b))||judge(q2,point(q2.a,q1.b))||judge(q2,point(q1.a,q2.b)))
printf("T\n");
else
printf("F\n");
}

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: