现在的位置: 首页 > 综合 > 正文

JOJ 1984: A Round Peg in a Ground Hole (判断点在凸多边形内)

2013年10月11日 ⁄ 综合 ⁄ 共 1959字 ⁄ 字号 评论关闭

之前的代码,整理一下,计算几何已经被我忘差不多了 。。。

#include<iostream>
#include<cstdio>
#include<cmath>
const double pi=acos(-1.0);
const double eps = 1e-8;
const int  maxn=1000;
struct point
{
    double x,y;
    point operator-(point p)
    {
        point res;
        res.x = x - p.x;
        res.y = y - p.y;
        return res;
    }
};

struct circle{
    point c;
    double r;
};

double dis(point p1, point p2){
    point p3 = p2 - p1;
    return sqrt(p3.x * p3.x + p3.y * p3.y);
}

double multi(point p1, point p2){
    return p1.x * p2.y - p1.y * p2.x;
}

void ChangeDir(point p[], int n)
{
    point tmp;
    for(int i = 0;i < n / 2;i++)
    {
        tmp = p[i];
        p[i] = p[n - i - 1];
        p[n - i - 1] = tmp;
    }
}

double AreaOfPloy(point p[], int n){
    double area = 0.0;
    for(int i = 0;i < n;i++)
        area += multi(p[i], p[i + 1]);
    return area / 2;
}

double AreaOfThree(point p1, point p2, point p3){
    return fabs(multi(p2 - p1, p3 - p1)) / 2;
}

void OutPoint(point q){
    printf("(%.2lf %.2lf) ", q.x, q.y);
}

int IsConvex(point p[], int n){ /* 判断是否凸多边形 */
    for(int i = 1;i <= n;i++)
        if(multi(p[i % n] - p[i - 1], p[(i + 1) % n] - p[i % n]) < 0) return 0;
    return 1;
}

int IsInConvex(point p[], int n, point q) /* 点是否在凸多边形内 */{
    double area = 0.0;
    for(int i = 0;i < n;i++)
        area += AreaOfThree(q, p[i], p[i + 1]);
    if(fabs(area - fabs(AreaOfPloy(p, n))) < eps) return 1;
    return 0;
}

double min(double a, double b){
    return a < b ? a : b;
}

double disPointToSeg(point p1, point p2, point p3){
    double a = dis(p1, p2);
    double b = dis(p1, p3);
    double c = dis(p2, p3);
    if(fabs(a + b - c) < eps) return 0;
    if(fabs(a + c - b) < eps || fabs(b + c - a) < eps) return min(a, b);
    double t1 = -a * a + b * b + c * c;
    double t2 = a * a - b * b + c * c;
    if(t1 <= 0 || t2 <= 0) return min(a, b);
    double l = (a + b + c) / 2;
    double s = sqrt(l * (l - a) * (l - b) * (l - c));
    return 2 * s / c;
}

int main()
{
    //freopen("pD1.in", "r", stdin);
    //freopen("outbie.out", "w", stdout);
    int n;
    circle peg;
    point p[1000];
    while(scanf("%d", &n) != EOF)
    {
        if(n < 3) break;
        scanf("%lf%lf%lf", &peg.r, &peg.c.x, &peg.c.y);
        for(int i = 0;i < n;i++)
            scanf("%lf%lf", &p[i].x, &p[i].y);
        p[n] = p[0];
        if(AreaOfPloy(p, n) < 0) ChangeDir(p, n);
        p[n] = p[0];
        if(!IsConvex(p, n))
        {
            printf("HOLE IS ILL-FORMED\n");
            continue;
        }
        if(!IsInConvex(p, n, peg.c))
        {
            printf("PEG WILL NOT FIT\n");
            continue;
        }
        int success = 1;
        for(int i = 0;i < n;i++)
            if(disPointToSeg(peg.c, p[i], p[i + 1]) < peg.r)
            {
                success = 0;
                printf("PEG WILL NOT FIT\n");
                break;
            }
        if(success == 1) printf("PEG WILL FIT\n");
    }
    return 0;
}


 

抱歉!评论已关闭.