fzu 2273 几何学
程序员文章站
2022-03-02 10:57:24
...
Problem 2273 Triangles
Accept: 207 Submit: 701
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
2
0 0 0 1 1 0 10 10 9 9 9 10
0 0 1 1 1 0 0 0 1 1 0 1
Sample Output
disjoint
intersect
题意: 给你 6 个点 前三个点为一个三角形,后三个点为一个三角形。 问你两个三角形是相交 相离 还是包含关系
思路:我们怎么判断三角形相含呢 肯定是一个三角形的三个点 都在另一个三角形的内部。我们怎么判断一
个点是否在另一个三角形的内部呢? 有两种方法,第一种就是 判断这个点和三角形的任意一条边组成
的三角形的面积和 如果大于原三角形的面积 那么肯定就是在外部 不然就是在内部或者在边上,
第二种方法 就是做叉乘 假设一个三角形的三个点为a,b,c 点d 是否在内部 我们将向量
ab 与向量ad 得到ans1 向量ab 与向量ac 做叉乘得到ans2 如果正负相
同 表示 c 和d 在同一边 这样对于 bc 判断 ad 是否在同一边 对于ca 判断 bd 是否在一边。
那我们怎么判断三角形是相交呢? 可以通过判断这个三角形的任意一条边 是否和 另一个三角形的
边相交。判断两个线段相交: 线段是否相交
其他的情况肯定就是 相离。
代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-8;
/*
typedef struct point
{
double x,y;
point(double x=0,double y=0 ):x(x),y(y){}
}vvecotr;
*/
typedef struct point
{
double x,y;
point(double x=0,double y=0):x(x),y(y){}
}vvector;
vvector operator + (const vvector &a,const vvector &b)
{
return vvector(a.x+b.x,a.y+b.y);
}
vvector operator - (const vvector &a,const vvector &b)
{
return vvector(a.x-b.x,a.y-b.y);
}
vvector operator * (const vvector &a,double p)
{
return vvector(a.x*p,a.y*p);
}
vvector operator / (const vvector &a,double p)
{
return vvector(a.x/p,a.y/p);
}
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
return x<0?-1:1;
}
double dot(const vvector &a,const vvector &b)
{
return a.x*b.x+a.y*b.y;
}
double corss(const vvector &a,const vvector &b)
{
return a.x*b.y-b.x*a.y;
}
bool judxianduanjiao(const point &a1,const point &a2,const point &b1,const point &b2)
{
double c1=corss(a2-a1,b1-a1); double c2=corss(a2-a1,b2-a1);
double c3=corss(b2-b1,a1-b1); double c4=corss(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<=0&&dcmp(c3)*dcmp(c4)<=0;
}
bool sameside(point a,point b,point c,point d)
{
vvector ab=b-a,ac=c-a,ad=d-a;
double jud1=corss(ab,ac);
double jud2=corss(ab,ad);
if(jud1*jud2>=0) return 1;
return 0;
}
bool intri(point a,point b,point c,point d)
{
return sameside(a,b,c,d)&&sameside(b,c,a,d)&&sameside(c,a,b,d);
}
point p[7];
int main()
{
int cas;
cin>>cas;
while(cas--)
{
for(int i=0;i<6;i++)
{
cin>>p[i].x>>p[i].y;
}
int flag=0;
for(int i = 0; i<3; i++){
if(judxianduanjiao(p[i],p[(i+1)%3],p[3],p[4]) || judxianduanjiao(p[i],p[(i+1)%3],p[3],p[5]) || judxianduanjiao(p[i],p[(i+1)%3],p[5],p[4]))
{
flag = 1;
break;
}
}
//printf("flag : %d \n",flag);
if(flag)
{
printf("intersect\n");
continue;
}
if(intri(p[0],p[1],p[2],p[3])&&intri(p[0],p[1],p[2],p[4])&&intri(p[0],p[1],p[2],p[5]))
{
printf("contain\n");
continue;
}
if(intri(p[3],p[4],p[5],p[0])&&intri(p[3],p[4],p[5],p[0])&&intri(p[3],p[4],p[5],p[0]))
{
printf("contain\n");
continue;
}
printf("disjoint\n");
}
return 0;
}
上一篇: 点到线段的最短距离
下一篇: C++-计算点到三角形距离代码
推荐阅读