Problem 2273 Triangles 判断两个三角形的相对位置(相交/包含/远离)

两个三角形是不是相交的:先是看三角形的线段是否相交(不含端点),然后看三角形的端点是不是在另外一个三角形的边上(边不含端点),最后看端点是不是相等的。满足其中一点即为相交

两个三角形是不是包含的:看点在不在三角形内

两个三角形是不是远离的:其他

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>

using namespace std;


struct point {
  double x,y;
  point(double x1=0,double y1=0){x=x1;y=y1;}
};

typedef point Vector;

Vector operator +(point a,point b)
{
    return Vector(a.x+b.x,a.y+b.y);
}
Vector operator *(point a,double b)
{
    return Vector(a.x*b,a.y*b);
}
Vector operator -(point a,point b)
{
    return Vector(a.x-b.x,a.y-b.y);
}

double dot(Vector a,Vector b)//点乘
{
    return a.x*b.x+a.y*b.y;
}

double cross(Vector a,Vector b)//叉乘
{
    return a.x*b.y-a.y*b.x;
}

double len (Vector a)
{
    return sqrt(a.x*a.x+a.y*a.y);
}

Vector rotate1(Vector a,double rad)//逆时针旋转rad
{
    return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
}

point getans (point p,Vector v,point q,Vector w)//求两条直线的交点,唯一交点,当且仅当不共线
{
    Vector u=p-q;
    double t=cross(w,u)/cross(v,w);
    return p+v*t;
}
const double eps = 1e-10;
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else return x<0? -1:1;
}
bool operator == (const point& a,const point& b)
{
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}


bool seg(point a1,point a2,point b1,point b2)//两线段是否相交,不包括端点
{
    double c1=cross(a2-a1,b1-a1),c2=cross(a2-a1,b2-a1);
    double d1=cross(b2-b1,a1-b1),d2=cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0&&dcmp(d1)*dcmp(d2)<0;
}
bool os(point p,point a1,point a2)//p点在线段a1a2上且不含端点
{
    if(dcmp(cross(a1-p,a2-p))==0&&dcmp(dot(a1-p,a2-p))<0)
        return 1;
    else return 0;
}
point a[10],b[10];

int isp(point d,point *p)
{
    int wn = 0;
    int n=3;
    for(int i=0;i<3;i++)
    {
        if(os(d,p[i],p[(i+1)%n])) return -1;//点在边界上
        int k=dcmp(cross(p[(i+1)%n]-p[i],d-p[i]));
        int d1=dcmp(p[i].y-d.y);
        int d2=dcmp(p[(i+1)%n].y-d.y);
        if(k>0&&d1 <= 0 &&d2 > 0) wn++;
        if(k<0 &&d2<=0&&d1>0) wn--;
    }
    if(wn != 0) return 1;//内部
    return 0;//外部
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",&a[0].x,&a[0].y,&a[1].x,&a[1].y,&a[2].x,&a[2].y,&b[0].x,&b[0].y,&b[1].x,&b[1].y,&b[2].x,&b[2].y);
        int flag=0;
        for(int i=0;i<3;i++)
        {
            for(int j=0;j<3;j++)
            {
                if(seg(a[i],a[(i+1)%3],b[i],b[(i+1)%3])) {flag=1;break;}
                if(os(a[i],b[i],b[(i+1)%3])) {flag=1;break;}
                if(a[i]==b[i]) {flag=1;break;}
            }
        }
        if(flag) printf("intersect\n");
        else {
            if(isp(b[0],a)==1&&isp(b[1],a)==1&&isp(b[2],a)==1) flag=1;
            else if(isp(a[0],b)==1&&isp(a[1],b)==1&&isp(a[2],b)==1) flag=1;
            if(flag) printf("contain\n");
            else printf("disjoint\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值