【计算几何】fzuoj 2273 Triangles

来源:互联网 发布:ichart.js 编辑:程序博客网 时间:2024/05/29 05:08

 Problem 2273 Triangles

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

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

 Source

第八届福建省大学生程序设计竞赛-重现赛(感谢承办方厦门理工学院)

Submit  Back  Status  Discuss
题意:给出两个三角形的坐标判断这两个三角形的位置关系:相交?相离?包含

思路:先判断是否两个三角形的任意线段是否相交,若不想交,则应该是包含或者相离;接下来判断一个三角形的点是否在另一个三角形的内部,若在则包含,否则相离;

代码:

#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的面积;





原创粉丝点击