poj 1584 A Round Peg in a Ground Hole(叉积判断凸多边形)

题意:给出一个多边形和每个点的坐标,以及一个圆的圆心坐标和半径,让你判断该园能否放入这个多边形中。

思路:先判断该多边形是否是凸多边形,由于给出多边形的坐标可能是顺时针方向也可能是逆时针方向,所以判断时分两种情况,如果是凸多边形,在判断该圆的圆心是否在多边形内部,这也可以用叉乘来判断,最后判断圆心到边的距离是否都大于圆的半径。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#define N 102
using namespace std ;

struct node
{
    double x ;
    double y ;
}p[N];

int n ;
double xx , yy ;
double rad;
//判断多边形为凸多边形
int jud_shap ( int k )
{
    int i ;
    int flag = 0 ;
    if ( k == 1 )
    {
        flag = 0 ;
        for ( i = 0 ; i < n ; i++ )
        {
            double pi = (p[(i+1)%n].x-p[i].x)*(p[(i+2)%n].y-p[(i+1)%n].y);
            double qi = (p[(i+2)%n].x-p[(i+1)%n].x)*(p[(i+1)%n].y-p[i].y);
            if ( pi > qi )
            {
                flag = 1 ; break;
            }
        }
        if ( flag ) return 0;
        return 1 ;
    }
    if ( k == 2 )
    {
        for ( i = 0 ; i < n ; i++ )
        {
            double pi = (p[(i+1)%n].x-p[i].x)*(p[(i+2)%n].y-p[(i+1)%n].y);
            double qi = (p[(i+2)%n].x-p[(i+1)%n].x)*(p[(i+1)%n].y-p[i].y);
            if ( pi < qi )
            {
                flag = 1 ; break;
            }
        }
        if ( flag )
        return 0;
        else
        return 1 ;
    }
}
//计算圆心到直线的距离
int jud ( struct node p1 , struct node p2 )
{
    double a = p1.y - p2.y ;
    double b = p2.x - p1.x ;
    double c = p2.y * p1.x - p2.x *p1.y ;
    double dis = fabs( a * xx + b * yy + c ) / ( sqrt ( a * a + b * b ));
    if ( dis < rad )
    return 0 ;
    else
    return 1 ;
}
//判断圆心是否在凸多边形内部
int jud_cir( )
{
    int i , flag ;
    double x1, y1 , x2 , y2 ;
    double line1 , line2 ;

    flag = 0 ;
    for ( i = 0 ; i < n ; i++ )
    {
        x1 = p[(i+1)%n].x - p[i].x ;
        y1 = p[(i+1)%n].y - p[i].y ;
        x2 = p[(i+1)%n].x - xx ;
        y2 = p[(i+1)%n].y - yy ;
        line1 = x1 * y2 - x2 * y1 ;
        x1 = p[(i+1)%n].x - p[(i+2)%n].x ;
        y1 = p[(i+1)%n].y - p[(i+2)%n].y ;
        x2 = p[(i+1)%n].x - xx ;
        y2 = p[(i+1)%n].y - yy ;
        line2 = x1 *y2 - x2 * y1 ;
        if ( line1 *line2 > 0 )//如果两条直线在一边,则圆心在多边形外面
        {
            flag = 1 ; break;
        }
        if ( !jud( p[i] , p[(i+1)%n]))
        {
            flag = 1 ; break;
        }
    }
    if ( flag ) return 0 ;
    return 1 ;
}

int main()
{
    int i , j , flag ;

    while ( scanf ( "%d" , &n ) != EOF )
    {
        if ( n < 3 ) break;
        scanf ( "%lf%lf%lf" , &rad , &xx ,&yy );
        for ( i = 0 ; i < n ; i++ )
        scanf ( "%lf%lf" , &p[i].x , &p[i].y );
        double k = ((p[1].x-p[0].x)*(p[2].y-p[1].y))-((p[2].x-p[1].x)*(p[1].y-p[0].y));
        if ( k < 0 )
        flag = jud_shap( 1 ) ;
        else
        flag = jud_shap( 2 );
        if ( flag )
        {
            if ( jud_cir())
            printf ( "PEG WILL FIT\n" );
            else
            printf ( "PEG WILL NOT FIT\n" );
        }
        else
        printf ( "HOLE IS ILL-FORMED\n" );
    }
    return 0 ;
}
posted @ 2012-07-17 11:37  Misty_1  阅读(169)  评论(0编辑  收藏  举报