POJ 3449 Geometric Shapes 判断各种图形是否相交

题意:给你一些图形,输入点,判断各个图形的相交情况。

分析: 输入输出比较麻烦,其它很水。

注意点:

1. 是正方形的话给你两个点是对角线的两端点,会求另外两点的坐标。

已知 (x1, y1),(x3, y3) 求(x2, y2),(x4, y4);

可以由方程组:

x1 + x3 = x2 + x4;

x1 -  x3 = y2 - y4 ;

y1 + y3 = y2 + y4;

y3 -  y1 = x2 - x4 ;

解方程一下即可。

2.多边形和矩形都是按顺序输入点的,也就是说按连边的顺序输入。

3.输出的时候,如果相交要考虑多种情况。

注意这里的输出:

跟 1 个相交 with B

跟 2 个相交 with B and F   ,注意   B 后面and前面  没有逗号, 坑了我一会。

跟 3个以上相交 with S, W, and X, 注意  W后面and前面  有逗号。

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
#define eps 10e-8

struct point
{
    double x, y;
};

int num, n;
vector<int>v[27];

 //以下是汝的黑书求两线段模板 (极少部分名称被我修改过)
double crossdet(double x1, double y1, double x2, double y2)
{
    return x1 * y2 - x2 * y1;
}
double cross(point o, point a, point b)
{
    return crossdet(a.x - o.x, a.y - o.y, b.x - o.x, b.y - o.y);
}
double dotdet(double x1, double y1, double x2, double y2)
{
    return x1 * x2 + y1 * y2;
}
double dot(point o, point a, point b)
{
    return dotdet(a.x - o.x, a.y - o.y, b.x - o.x, b.y - o.y);
}
int dblcmp(double d)
{
    if( fabs(d) < eps)return 0;
    return d > 0 ? 1 : -1;
}
int between(point a, point b, point c)
{
    return dblcmp( dot(a, b, c));
}
int seg_cross(point a, point b, point c, point d)
{
    double s1, s2, s3, s4;
    int d1, d2, d3, d4;
    d1 = dblcmp (s1 = cross(a, b, c));
    d2 = dblcmp (s2 = cross(a, b, d));
    d3 = dblcmp (s3 = cross(c, d, a));
    d4 = dblcmp (s4 = cross(c, d, b));
    if( (d1 ^ d2) == -2 && (d3 ^ d4) == -2)return 1;
    if( d1 == 0 && between(c, a, b) <= 0
     || d2 == 0 && between(d, a, b) <= 0
     || d3 == 0 && between(a, c, d) <= 0
     || d4 == 0 && between(b, c, d) <= 0)return 1;
    return 0;
}



struct node
{
    char no[4], kind[15], cnt;
    point p[22];
}a[27];

bool cmp(node a, node b)
{
    return a.no[0] < b.no[0];
}

void input()
{
    char c;
    int i, j;
    scanf("%s",a[num].kind);
    c = a[num].kind[0];
    if(c == 'p')
    {
        scanf("%d", &n);
        a[num].cnt = n + 1;
        for(i = 1; i <= n; i++)
            scanf(" (%lf,%lf)", &a[num].p[i].x, &a[num].p[i].y);
        a[num].p[n + 1].x = a[num].p[1].x;
        a[num].p[n + 1].y = a[num].p[1].y;
    }
    else if(c == 'l')
    {
        a[num].cnt = 2;
        for(i = 1; i <= 2; i++)
            scanf(" (%lf,%lf)", &a[num].p[i].x, &a[num].p[i].y);
    }
    else if(c == 't')
    {
        a[num].cnt = 4;
        for(i = 1; i <= 3; i++)
            scanf(" (%lf,%lf)", &a[num].p[i].x, &a[num].p[i].y);
        a[num].p[4].x = a[num].p[1].x;
        a[num].p[4].y = a[num].p[1].y;
    }
    else if(c == 's')
    {
        a[num].cnt = 5;
        for(i = 1; i <= 3; i += 2)
            scanf(" (%lf,%lf)", &a[num].p[i].x, &a[num].p[i].y);
        a[num].p[2].x = ( a[num].p[1].x + a[num].p[3].x + a[num].p[3].y - a[num].p[1].y) / 2.0;
        a[num].p[4].x = ( a[num].p[1].x + a[num].p[3].x - a[num].p[3].y + a[num].p[1].y) / 2.0;
        a[num].p[2].y = ( a[num].p[1].x - a[num].p[3].x + a[num].p[1].y + a[num].p[3].y) / 2.0;
        a[num].p[4].y = ( a[num].p[3].x - a[num].p[1].x + a[num].p[1].y + a[num].p[3].y) / 2.0;
        a[num].p[5].x = a[num].p[1].x;
        a[num].p[5].y = a[num].p[1].y;
    }
    else if(c == 'r')
    {
        a[num].cnt = 5;
        for(i = 1; i <= 3; i++)
            scanf(" (%lf,%lf)", &a[num].p[i].x, &a[num].p[i].y);
        a[num].p[4].x = a[num].p[1].x + a[num].p[3].x - a[num].p[2].x;
        a[num].p[4].y = a[num].p[1].y + a[num].p[3].y - a[num].p[2].y;
        a[num].p[5].x = a[num].p[1].x;
        a[num].p[5].y = a[num].p[1].y;
    }
    num++;
}

int main()
{
    int i, j, k, x;
    num = 0;
    while( scanf("%s", a[num].no ) != EOF )
    {
        if(a[num].no[0] == '.')break;
        input();
        while( scanf("%s", a[num].no ) != EOF && a[num].no[0] != '-')
        {
            input();
        }
        sort(a, a+num,cmp);
        for(i = 0; i <= 26; i++)
            v[i].clear();
        bool flag = 0;
        for(i = 0; i < num; i++)
            for(j = i + 1; j < num; j++)
            {
                for(x = 1; x < a[i].cnt; x++)
                {
                    for(k = 1; k < a[j].cnt; k++)
                    {
                        if(seg_cross(a[i].p[x], a[i].p[x+1], a[j].p[k], a[j].p[k+1]))
                        {
                            flag = 1;v[i].push_back(j);v[j].push_back(i);break;
                        }
                    }
                    if( k != a[j].cnt)break;
                }
            }    
        for(i = 0; i < num; i++)
        {
            printf("%c ",a[i].no[0]);
            int len = v[i].size();
            if(len == 0)printf("has no intersections\n");
            else if(len == 1)printf("intersects with %c\n", a[ v[i][0] ].no[0]);
            else if(len == 2)printf("intersects with %c and %c\n", a[ v[i][0] ].no[0], a[ v[i][1] ].no[0]);
            else
            {
                printf("intersects with ");
                for(j = 0; j < len - 1; j++)
                    printf("%c, ", a[ v[i][j] ].no[0]);
                printf("and %c\n",a[ v[i][len - 1] ].no[0]);
            }
        }
        puts("");
        num = 0;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值