Triangles(VJ)补题

Triangles

Accept: 373 Submit: 1263
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

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define eps 1e-8
#define zero(x) (((x)>0?(x):(-x))<eps)
 
using namespace std;
 
struct point{double x,y;};
struct triangle{point a,b,c;};
 
///计算叉积
/**
设向量A=p1-p0,B=p2-p0;
    |     i           j       k   |
AxB=| p1.x-p0.x   p1.y-p0.y   0   |
    | p2.x-p0.x   p2.y-p0.y   0   |
*/
 
double xmult(point p1,point p2,point p0){
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
 
///判断三点共线
/**
若三点共线 设向量A=p1-p0,B=p2-p0;
|AxB|=|A||B|sin<A,B>,又三点共线,所以<A,B>=0,所以|AxB|=0;
*/
int dots_inline(point p1,point p2,point p3){
    return zero(xmult(p1,p2,p3));
}
///判断两点在线段同侧
/**
设向量 A=l2-l1,B=p2-l1,C=p1-l1;
由右手定则可以得出,若p1,p2两点同侧,则|AxB|与|AxC|同正负;
若p1或p2在线段上,则|AxC|或|AxB|等于0
*/
int same_side(point p1,point p2,point l1,point l2){
    return xmult(l1,p1,l2) * xmult(l1,p2,l2) > eps;
}
///判断点是否在线上,包括端点
/**
1.先判三点共线;
2.再判点是否在线段上,如果在,则两个端点的横坐标与该点的横坐标(纵坐标)之差的积小于或者等于零;
*/
int dot_online_in(point p,point l1,point l2){
    return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x) < eps && (l1.y-p.y)*(l2.y-p.y) < eps;
}
 
///判断两线相交,包括部分重合和点重合
/**
1.先判是否共线,如果不共线,看其中一条边的两个端点是否在另一条线段的两侧;
2.判断点是否在线段上;
*/
int intersect_in(point u1,point u2,point v1,point v2){
    if(!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))
        return !same_side(u1,u2,v1,v2) && !same_side(v1,v2,u1,u2);
    return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);
}
 
///计算面积
/**
S=|AxB|/2;
*/
double area_triangle(point p1,point p2,point p3){
    return fabs(xmult(p1,p2,p3))/2;
}
///判断点是否包含在三角形内部,包括三条边上
/**
大三角形与三个小三角形的面积之差是否为零
*/
int dot_triangle_in(triangle p1,point p0){
    return fabs(area_triangle(p1.a,p1.b,p1.c)-area_triangle(p1.a,p1.b,p0)-area_triangle(p1.a,p0,p1.c)-area_triangle(p0,p1.b,p1.c))<eps;
}
 
void solve_question(){
    point a[3],b[3];
    triangle A,B;
    for(int i=0;i<3;i++)
        cin >> a[i].x >> a[i].y;
    for(int i=0;i<3;i++)
        cin >> b[i].x >> b[i].y;
    A = (triangle){a[0],a[1],a[2]};
    B = (triangle){b[0],b[1],b[2]};
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            if(intersect_in(a[i],a[(i+1)%3],b[j],b[(j+1)%3])) { printf("intersect\n");return;}
    if(dot_triangle_in(A,b[0]) || dot_triangle_in(B,a[0]))
        printf("contain\n");
    else
        printf("disjoint\n");
 
}
 
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        solve_question();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值