Live2d Test Env

HDU - 5130 :Signal Interference (多边形与圆的交)

pro:A的监视区域是一个多边形。 如果A的监视区的内满足到A的距离到不超过到B的距离的K倍的面积大小。K<1

sol:高中几何体经验告诉我们满足题意的区域是个圆,那么就是求圆与多边形的交。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=200010;
const double eps=1e-12;
struct point{
    double x,y;
    point(){}
    point(double xx,double yy):x(xx),y(yy){}
};
struct Circle{
    point c; double r;
};
double det(point a,point b){ return a.x*b.y-a.y*b.x;}
double dot(point a,point b){ return a.x*b.x+a.y*b.y;}
point operator *(point a,double t){ return point(a.x*t,a.y*t);}
point operator +(point a,point b){ return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){ return point(a.x-b.x,a.y-b.y);}
double Length(point A){return sqrt(dot(A,A));}
int dcmp(double x){
    if(fabs(x)<eps) return 0;  if(x<0) return -1; return 1;
}
double TriAngleCircleInsection(Circle C, point A, point B)
{
    point OA=A-C.c,OB=B-C.c;
    point BA=A-B, BC=C.c-B;
    point AB=B-A, AC=C.c-A;
    double DOA=Length(OA),DOB=Length(OB),DAB=Length(AB),r=C.r;
    if(dcmp(det(OA,OB))==0) return 0; //,三点一线,不构成三角形
    if(dcmp(DOA-C.r)<0&&dcmp(DOB-C.r)<0) return det(OA,OB)*0.5; //内部
    else if(DOB<r&&DOA>=r) //一内一外
    {
        double x=(dot(BA,BC)+sqrt(r*r*DAB*DAB-det(BA,BC)*det(BA,BC)))/DAB;
        double TS=det(OA,OB)*0.5;
        return asin(TS*(1-x/DAB)*2/r/DOA)*r*r*0.5+TS*x/DAB;
    }
    else if(DOB>=r&&DOA<r)// 一外一内
    {
        double y=(dot(AB,AC)+sqrt(r*r*DAB*DAB-det(AB,AC)*det(AB,AC)))/DAB;
        double TS=det(OA,OB)*0.5;
        return asin(TS*(1-y/DAB)*2/r/DOB)*r*r*0.5+TS*y/DAB;
    }
    else if(fabs(det(OA,OB))>=r*DAB||dot(AB,AC)<=0||dot(BA,BC)<=0)//
    {
        if(dot(OA,OB)<0){
            if(det(OA,OB)<0) return (-acos(-1.0)-asin(det(OA,OB)/DOA/DOB))*r*r*0.5;
            else  return ( acos(-1.0)-asin(det(OA,OB)/DOA/DOB))*r*r*0.5;
        }
        else      return asin(det(OA,OB)/DOA/DOB)*r*r*0.5; //小于90度,以为asin对应的区间是[-90度,90度]
    }
    else //弧+三角形
    {
        double x=(dot(BA,BC)+sqrt(r*r*DAB*DAB-det(BA,BC)*det(BA,BC)))/DAB;
        double y=(dot(AB,AC)+sqrt(r*r*DAB*DAB-det(AB,AC)*det(AB,AC)))/DAB;
        double TS=det(OA,OB)*0.5;
        return (asin(TS*(1-x/DAB)*2/r/DOA)+asin(TS*(1-y/DAB)*2/r/DOB))*r*r*0.5 + TS*((x+y)/DAB-1);
    }
}
point a[maxn];
int main()
{
    int N,T,Ca=0; double K,ans;
    while (~scanf("%d%lf",&N,&K)) {
        rep(i,1,N) scanf("%lf%lf",&a[i].x,&a[i].y);
        a[N+1]=a[1];
        point A,B; Circle C;
        scanf("%lf%lf",&A.x,&A.y);
        scanf("%lf%lf",&B.x,&B.y);
        K=K*K;
        C.c.x=(B.x-A.x*K)/(1-K);
        C.c.y=(B.y-A.y*K)/(1-K);
        double ta=(K*A.x*A.x-B.x*B.x)/(1-K);
        double tb=pow((K*A.x-B.x)/(1-K),2);
        double tc=(K*A.y*A.y-B.y*B.y)/(1-K);
        double td=pow((K*A.y-B.y)/(1-K),2);
        C.r=sqrt(ta+tb+tc+td); ans=0;
        rep(i,1,N){
            ans+=TriAngleCircleInsection(C,a[i],a[i+1]);
        }
        printf("Case %d: %.10lf\n",++Ca,fabs(ans));
    }
    return 0;
}

 

posted @ 2019-04-09 22:08  nimphy  阅读(195)  评论(0编辑  收藏  举报