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