POJ 3384 Feng Shui Convex Hull Diameter+Half-plane Intersection

Links to the original text: http://www.cnblogs.com/riasky/p/3430851.html

G++ has not been replaced by C++ decisively A dropped... It's time to bet RP.


Topic: Give a polygon, and then put in two circles, so that the two circles cover the largest area, output the coordinates of the two centers.

Idea: Translating the radius R of the circle in the direction of the edge of the polygon, and then finding the two points with the longest distance of the new polygon.

The translation is a bit of a brain drain, and the rest are ready-made templates.

This is a translation function. I don't know if it's any easier. To move left and right, you just need to change the vector V.

 

void Panning_Edge(P &a1,P &a2,double dis)
{
    //Translation to the right of v
    P v = {a2.y-a1.y,a1.x-a2.x};

    double t = dis/Cal_Point_Dis(a1,a2);

    a1.x = a1.x+v.x * t;
    a1.y = a1.y+v.y * t;

    a2.x = a2.x+v.x*t;
    a2.y = a2.y+v.y*t;
}

 

 



PS: Well, I admit I didn't come up with it, and then I went through other people's questions... This inside pushing edge is really handy.

 

 

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <string>

#define LL long long
#define EPS (1e-9)
#define Right 1;
#define Left -1;

using namespace std;

struct P
{
    double x,y;
} p[55],tp[2510],cp[2510];

double X_Mul(P a1,P a2,P b1,P b2)
{
    P v1 = {a2.x-a1.x,a2.y-a1.y},v2 = {b2.x-b1.x,b2.y-b1.y};
    return v1.x*v2.y - v1.y*v2.x;
}

P Cal_Cross_Position(P a1,P a2,P b1,P b2)
{
    double t = fabs(X_Mul(a1,a2,a1,b1))/fabs(X_Mul(a1,a2,b2,b1));
    P p = {b1.x + (b2.x-b1.x)*t,b1.y + (b2.y-b1.y)*t};
    return p;
}

double Cal_Point_Dis(P a1,P a2)
{
    return sqrt((a2.x-a1.x)*(a2.x-a1.x) + (a2.y-a1.y)*(a2.y-a1.y));
}

void Panning_Edge(P &a1,P &a2,double dis)
{
    //Translation to the right of v
    P v = {a2.y-a1.y,a1.x-a2.x};

    double t = dis/Cal_Point_Dis(a1,a2);

    a1.x = a1.x+v.x * t;
    a1.y = a1.y+v.y * t;

    a2.x = a2.x+v.x*t;
    a2.y = a2.y+v.y*t;
}

int Cut_Polygon(P a1,P a2,P *tp,int n,P *cp,double rad)
{
    Panning_Edge(a1,a2,rad);

    double xm1,xm2;
    int i ,top = 0;
    for(i = 0;i < n; ++i)
    {
        xm1 = X_Mul(a1,a2,a1,tp[i]),xm2 = X_Mul(a1,a2,a1,tp[i+1]);
        if(xm1 < EPS && xm2 < EPS)
        {
            cp[top++] = tp[i];
        }
        else if(xm1 < EPS || xm2 < EPS)
        {
            if(xm1 < EPS)
            {
                cp[top++] = tp[i];
            }
            cp[top++] = Cal_Cross_Position(a1,a2,tp[i],tp[i+1]);
        }
    }
    cp[top] = cp[0];
    return top;
}

void Cal_Center_Position(P *tp,P *cp,P *p,int n,double rad)
{
    int i,j,top;

    for(i = 0;i <= n; ++i)
    {
        tp[i] = p[i];
    }

    for(top = n,i = 0;i < n; ++i)
    {
        top = Cut_Polygon(p[i],p[i+1],tp,top,cp,rad);
        for(j = 0;j <= top; ++j)
        {
            tp[j] = cp[j];
        }
        //Focus in Point Set
    }

   //Finding the diameter of convex hull, because the point set is not very big, I am too lazy to write the rotating hull.

   double TempDis,MaxDis = -1;
   int s1,s2;

   for(i = 0;i <= top; ++i)
   {
       for(j = 0;j <= top; ++j)
       {
           TempDis = Cal_Point_Dis(tp[i],tp[j]);
           if(MaxDis < TempDis)
           {
               MaxDis = TempDis,s1 = i,s2 = j;
           }
       }
   }

   //Final answer
   printf("%.4lf %.4lf %.4lf %.4lf\n",tp[s1].x,tp[s1].y,tp[s2].x,tp[s2].y);

}

int main()
{
    int i,n;
    double rad;
    while(scanf("%d %lf",&n,&rad) != EOF)
    {
        for(i = 0; i < n; ++i)
        {
            scanf("%lf %lf",&p[i].x,&p[i].y);
        }

        p[n] = p[0];

        Cal_Center_Position(tp,cp,p,n,rad);
    }
    return 0;
}

 

 

 

Reprinted at: https://www.cnblogs.com/riasky/p/3430851.html

Keywords: REST

Added by like_duh44 on Mon, 14 Oct 2019 22:30:34 +0300