欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

fzu 2273 几何学

程序员文章站 2022-03-02 10:57:24
...
Problem 2273 Triangles

Accept: 207    Submit: 701
Time Limit: 1000 mSec    Memory Limit : 262144 KB

fzu 2273 几何学 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.)

fzu 2273 几何学 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

fzu 2273 几何学 Output

For each test case, output “intersect”, “contain” or “disjoint”.

fzu 2273 几何学 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

fzu 2273 几何学 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;
} 

相关标签: 计算几何