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

来源:互联网 发布:winpe 加载网络 编辑:程序博客网 时间:2024/05/21 06:45

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

#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;}