Geometric Shapes POJ - 3449 (Computational Geometry + line intersection + care)

Keywords: P4

Geometric Shapes POJ - 3449
Classification: carefulness + line intersection
Extras: a tot has been written as 0, and I've been looking for bug s all morning. I want to kill myself carelessly and cry all the time. The problem is really not difficult! But the code is a little long! Be careful, do not copy and paste repeatedly, it's deadly.
Give you a bunch of coordinates (lines, triangles, squares, rectangles, polygons) of figures and ask them about their intersection.
Train of thought:
1. To deal with the problem of storage, the points of different shapes are stored in order, with three triangles and four rectangles in an array. Finally, according to
2. Judge the intersection of graphs (there are many ways to judge the intersection of line segments, so it is necessary to see which is the intersection of questions), store them in order, just traverse graph i (1-tot), compare with all the line segments of graph j (i+1-tot), and save the results.
3. Classification output.

About the point calculation of rectangle and square. The intersection of diagonals is given.
Square, known (x0,y0) and (x2,y2) can be calculated according to the following relations (x1,y1),(x3,y3), the same as rectangle
x1+x3 = x0+x2;
x1-x3 = y2-y0;
x1=(x0+x2+y2-y0)/2;
x3=(x0+x2-y2+y0)/2
y1+y3 = y0-y2;
y1-y3 = x0-x2;

AC Code:

//It's not difficult, but it's a bit troublesome
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=30;
const double eps=1e-8;
vector<int> ans[N];
struct point{
    double x,y;
    point(){}
    point(double _X,double _Y){x=_X;y=_Y;}
};
struct edge
{
    char id;
    int num;//Number of edges
    point p[N];
    edge(){}
    bool operator <(const edge &u)const{
        return id<u.id;//Sort from small to large
    }
    //edge(point a,point b){start=a,end=;b}
}shapes[N];int tot;
//Judge the intersection of line segments
int sgn(double x)
{
    if(fabs(x) < eps)return 0;
    if(x < 0)return -1;
    else return 1;
}
double multi(point p1,point p2,point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
bool inter(point p1,point p2,point p3,point p4)
{
    return
    max(p1.x,p2.x) >= min(p3.x,p4.x)&&
    max(p3.x,p4.x) >= min(p1.x,p2.x)&&
    max(p1.y,p2.y) >= min(p3.y,p4.y)&&
    max(p3.y,p4.y) >= min(p1.y,p2.y)&&
    sgn(multi(p3,p1,p2))*sgn(multi(p4,p1,p2))<=0&&
    sgn(multi(p1,p3,p4))*sgn(multi(p2,p3,p4))<=0;
}
bool check(edge a,edge b)
{
    for(int k=0;k<a.num;k++)
        for(int kk=0;kk<b.num;kk++)
           if(inter(a.p[k],a.p[(k+1)%a.num],b.p[kk],b.p[(kk+1)%b.num]))
            return true;
    return false;
}
//Initialization
void init()
{

    for(int i=0;i<tot;i++)
        ans[i].clear();
    tot=0;
}
//Print results
void print()
{
    for(int i=0;i<tot;i++)
    {
        printf("%c ",shapes[i].id);
        if(ans[i].size()==0) printf("has no intersections\n");
        else if(ans[i].size()==1) printf("intersects with %c\n",shapes[ans[i][0]].id);
        else if(ans[i].size()==2) printf("intersects with %c and %c\n",shapes[ans[i][0]].id,shapes[ans[i][1]].id);
        else if(ans[i].size()>2)
        {
            int len=ans[i].size();
            printf("intersects with ");
            for(int j=0;j<len-1;j++)
                printf("%c, ",shapes[ans[i][j]].id);
            printf("and %c\n",shapes[ans[i][len-1]].id);
        }
    }
    printf("\n");
}
//Process the stored information and judge which is intersected
void deal()
{
    sort(shapes,shapes+tot);
    for(int i=0;i<tot;i++)
        for(int j=i+1;j<tot;j++)
            if(check(shapes[i],shapes[j])) ans[i].push_back(j),ans[j].push_back(i);//i. j crossed
    print();
}
int main()
{
    string str;
    tot=0;
    while(cin>>str)
    {
        if(str[0]=='.') break;
        if(str[0]=='-')
        {
            if(tot==0) continue;
            deal();//Processing and output;
            init();continue;
        }
        shapes[tot].id=str[0];
        cin>>str;
        if(str=="square")
        {
            shapes[tot].num=4;
            scanf(" (%lf,%lf)",&shapes[tot].p[0].x,&shapes[tot].p[0].y);
            scanf(" (%lf,%lf)",&shapes[tot].p[2].x,&shapes[tot].p[2].y);
            shapes[tot].p[1].x = ((shapes[tot].p[0].x+shapes[tot].p[2].x)+(shapes[tot].p[2].y-shapes[tot].p[0].y))/2;
            shapes[tot].p[1].y = ((shapes[tot].p[0].y+shapes[tot].p[2].y)+(shapes[tot].p[0].x-shapes[tot].p[2].x))/2;
            shapes[tot].p[3].x = ((shapes[tot].p[0].x+shapes[tot].p[2].x)-(shapes[tot].p[2].y-shapes[tot].p[0].y))/2;
            shapes[tot].p[3].y = ((shapes[tot].p[0].y+shapes[tot].p[2].y)-(shapes[tot].p[0].x-shapes[tot].p[2].x))/2;

        }
        else if(str=="line")
        {
            shapes[tot].num=2;
            scanf(" (%lf,%lf)",&shapes[tot].p[0].x,&shapes[tot].p[0].y);
            scanf(" (%lf,%lf)",&shapes[tot].p[1].x,&shapes[tot].p[1].y);
        }
        else if(str=="triangle")
        {
            shapes[tot].num = 3;
            scanf(" (%lf,%lf)",&shapes[tot].p[0].x,&shapes[tot].p[0].y);
            scanf(" (%lf,%lf)",&shapes[tot].p[1].x,&shapes[tot].p[1].y);
            scanf(" (%lf,%lf)",&shapes[tot].p[2].x,&shapes[tot].p[2].y);
        }   
        else if(str=="rectangle")
        {
            shapes[tot].num = 4;
            scanf(" (%lf,%lf)",&shapes[tot].p[0].x,&shapes[tot].p[0].y);
            scanf(" (%lf,%lf)",&shapes[tot].p[1].x,&shapes[tot].p[1].y);
            scanf(" (%lf,%lf)",&shapes[tot].p[2].x,&shapes[tot].p[2].y);
            shapes[tot].p[3].x=shapes[tot].p[2].x+(shapes[tot].p[0].x-shapes[tot].p[1].x);
            shapes[tot].p[3].y=shapes[tot].p[2].y+(shapes[tot].p[0].y-shapes[tot].p[1].y);
        }
        else if(str=="polygon")
        {
            scanf("%d",&shapes[tot].num);
            for(int i=0;i<shapes[tot].num;i++)
            scanf(" (%lf,%lf)",&shapes[tot].p[i].x,&shapes[tot].p[i].y);
        }
        tot++;
    }
}

Posted by icedude on Thu, 02 Jan 2020 13:46:01 -0800