fzu 2273 几何学

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;
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值