【计算几何】fzuoj 2273 Triangles

本文介绍了一种通过计算判断两个三角形是否相交、相离或包含的方法,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 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

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

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

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

代码:

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





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值