您的位置:首页 > 其它

poj 1584 A Round Peg in a Ground Hole

2014-08-25 09:53 417 查看
叉乘的利用。

判断凸包用index作为凸包顺时针或逆时针的标记,若计算出的temp与标记异号,说明不是凸包

判断圆点是否在凸包内用叉乘,顺便计算各边与原点组成的三角形的有向面积

判断凸包是否在园内,计算远点到各边的距离与半径比较即可
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int n;
double pegr,area[155];
#define  eps  1e-8
struct point{
    double x,y;
}peg,p[155];
double dis(point a,point b){
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
double det(double x1,double y1,double x2,double y2){
    return x1*y2-x2*y1;
}
double cor(point b,point a,point d,point c){
    return  det(b.x-a.x,b.y-a.y,d.x-c.x,d.y-c.y);
}
int precision(double a){
    if(fabs(a)<eps){
        return 0;
    }
    return a>0?1:-1;
}
bool convex(){
    int i=0;
    int index=precision(cor(p[(i+1)%n],p[i],p[(i+2)%n],p[i]));
    while(!index&&i<n){
          i++;
          index=precision(cor(p[(i+1)%n],p[i],p[(i+2)%n],p[i]));
    }
    i++;
    for(;i<n;i++){
         int temp=precision(cor(p[(i+1)%n],p[i],p[(i+2)%n],p[i]));
         if(temp*index<0)
            return false;
         }
    return true;
}
bool inside(){
    int i=0;
    area[i]=cor(p[i],peg,p[(i+1)%n],peg);
    int index=precision(area[i]);
    while(!index&&i<n){
          i++;
          area[i]=cor(p[i],peg,p[(i+1)%n],peg);
          index=precision(area[i]);
    }
    i++;
    for(;i<n;i++){
         area[i]=cor(p[i],peg,p[(i+1)%n],peg);
         int temp=precision(area[i]);
         if(temp*index<0)
            return false;
         }
    return true;
}
bool contain(){
    int i=0;
    for(;i<n;i++){
        if(precision(area[i])<0)
            area[i]*=-1;
        double d=dis(p[i],p[(i+1)%n]);
        d=sqrt(d);
        //double area=cor(p[i],peg,p[(i+1)%n],peg);
        //cout<<"距离: "<<area/d<<' '<<pegr<<endl;
        if(area[i]/d<pegr){
            //cout<<area[i]/d<<' '<<i<<endl;
            return false;
        }
    }
    return true;
}
int main(){
   // freopen("D:\\INPUT.txt","r", stdin);
    while(cin>>n&&n>=3){
        cin>>pegr>>peg.x>>peg.y;
        //pegr*=pegr;
        //point p=new point
;//point p[155];
        int i=0;
        for(;i<n;i++){
            cin>>p[i].x>>p[i].y;
        }
        bool flag1=convex();
        if(flag1){
            bool flag2=inside();
            bool flag3=contain();
            //cout<<flag2<<' '<<flag3<<endl;
            if(flag2&&flag3){
                cout<<"PEG WILL FIT"<<endl;
            }
            else{
                cout<<"PEG WILL NOT FIT"<<endl;
            }
        }
        else{
            cout<<"HOLE IS ILL-FORMED"<<endl;
        }
        //delete []p;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: