Accept: 43 Submit: 100
Time Limit: 1000 mSec Memory Limit : 262144 KB
Problem Description
This is a simple problem. Given two triangles A and B, you should determine they are intersect, contain or disjoint. (Public edge or point are treated as intersect.)
Input
First line contains an integer T (1 ≤ T ≤ 10), represents there are T test cases.
For each test case: X1 Y1 X2 Y2 X3 Y3 X4 Y4 X5 Y5 X6 Y6. All the coordinate are integer. (X1,Y1) , (X2,Y2), (X3,Y3) forms triangles A ; (X4,Y4) , (X5,Y5), (X6,Y6) forms triangles B.
-10000<=All the coordinate <=10000
Output
For each test case, output “intersect”, “contain” or “disjoint”.
Sample Input
Sample Output
Source
第八届福建省大学生程序设计竞赛-重现赛(感谢承办方厦门理工学院)
题意:给出两个三角形的坐标判断这两个三角形的位置关系:相交?相离?包含
思路:先判断是否两个三角形的任意线段是否相交,若不想交,则应该是包含或者相离;接下来判断一个三角形的点是否在另一个三角形的内部,若在则包含,否则相离;
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
struct point
{
double x,y;
} a[10];
double multi(point p0,point p1,point p2) //叉积
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
bool isIntersected(point s1,point e1,point s2,point e2)//判断两直线是否相交;
{
return (max(s1.x,e1.x)>=min(s2.x,e2.x))&&
(max(s2.x,e2.x)>=min(s1.x,e1.x))&&
(max(s1.y,e1.y)>=min(s2.y,e2.y))&&
(max(s2.y,e2.y)>=min(s1.y,e1.y))&&
(multi(s1,s2,e1)*multi(s1,e1,e2)>=0)&& //>=0包括重合;
(multi(s2,s1,e2)*multi(s2,e2,e1)>=0);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
int x,y;
for(int i=1; i<=6; i++)
{
scanf("%d%d",&x,&y);
a[i].x=x,a[i].y=y;
}
int xiangjiao=0;
int p1=isIntersected(a[1],a[2],a[4],a[5]); //判断是否有线段相交
int p2=isIntersected(a[1],a[2],a[4],a[6]);
int p3=isIntersected(a[1],a[2],a[5],a[6]);
int p4=isIntersected(a[1],a[3],a[4],a[5]);
int p5=isIntersected(a[1],a[3],a[4],a[6]);
int p6=isIntersected(a[1],a[3],a[5],a[6]);
int p7=isIntersected(a[2],a[3],a[4],a[5]);
int p8=isIntersected(a[2],a[3],a[4],a[6]);
int p9=isIntersected(a[2],a[3],a[5],a[6]);
if(p1||p2||p3||p4||p5||p6||p7||p8||p9)
xiangjiao=1;
int baohan=0;
if(!xiangjiao) //判断是否有点在另一个三角形内
{
double resa=fabs(multi(a[1],a[2],a[3]));
double res1=fabs(multi(a[1],a[2],a[4]))+fabs(multi(a[1],a[3],a[4]))+fabs(multi(a[2],a[3],a[4]));
double res2=fabs(multi(a[1],a[2],a[5]))+fabs(multi(a[1],a[3],a[5]))+fabs(multi(a[2],a[3],a[5]));
double res3=fabs(multi(a[1],a[2],a[6]))+fabs(multi(a[1],a[3],a[6]))+fabs(multi(a[2],a[3],a[6]));
double resb=fabs(multi(a[4],a[5],a[6]));
double res4=fabs(multi(a[4],a[5],a[1]))+fabs(multi(a[4],a[6],a[1]))+fabs(multi(a[5],a[6],a[1]));
double res5=fabs(multi(a[4],a[5],a[2]))+fabs(multi(a[4],a[6],a[2]))+fabs(multi(a[5],a[6],a[2]));
double res6=fabs(multi(a[4],a[5],a[3]))+fabs(multi(a[4],a[6],a[3]))+fabs(multi(a[5],a[6],a[3]));
if(fabs(res1-resa)<0.000001||fabs(res2-resa)<0.000001||fabs(res3-resa)<0.000001)
baohan=1;
if(fabs(res4-resb)<0.000001||fabs(res5-resb)<0.000001||fabs(res6-resb)<0.000001)
baohan=1;
}
if(xiangjiao)
printf("intersect\n");
else if(baohan)
printf("contain\n");
else
printf("disjoint\n");
}
return 0;
}
判断一个点是否在另一个三角形内是利用叉积的一个性质:向量的叉积等于组成的三角形的面积的一半;
若一个点在三角形A的内部,则这个点与A的三边所组成的三个三角形的面积和等于A的面积;