zoukankan      html  css  js  c++  java
  • 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 ;
    }
  • 相关阅读:
    [数学建模(八)]使用MATLAB绘图
    [数学建模(七)]使用MATLAB实现数据拟合
    [数学建模(六)]使用MATLAB实现插值
    [数学建模(五)]线性规划,二次规划和非线性规划的MATLAB求解
    [数学建模(四)]MATLAB神经网络工具箱的简单应用
    [数学建模(三)]遗传算法与旅行商问题
    [数学建模(二)模拟退火法与旅行商问题]
    [数学建模(一)]蒙特卡罗方法
    Java虚拟机13:Java类加载机制
    Java虚拟机14:类加载器
  • 原文地址:https://www.cnblogs.com/misty1/p/2594979.html
Copyright © 2011-2022 走看看