hdu 4404 Worms (2012金华网络赛E题)

多边形与圆的相交面积,把多边形分解成三角形处理,模版题。

特殊注意:正余弦反三角函数里的参数为+1、-1的时候会出错,把它们都乘上(1-EP)就可以了。

 

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
const double Pi=acos(-1.0);
const double EP=1e-10;
struct Point{
    double x,y;
};
double x_mult(Point sp, Point ep, Point op){
    return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);
}
double cross(Point a,Point b,Point c){
    return (a.x-c.x)*(b.x-c.x)+(a.y-c.y)*(b.y-c.y);
}
double dist(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cal_area(Point a,Point b,Point c,double r){
    double A,B,C,x,y,tS;
    A=dist(b,c);
    B=dist(a,c);
    C=dist(b,a);
    if(A<r&&B<r)
    return x_mult(a,b,c)/2;
    else if(A<r&&B>=r){
        x=(cross(a,c,b)+sqrt(r*r*C*C-x_mult(a,c,b)*x_mult(a,c,b)))/C;
        tS=x_mult(a,b,c)/2;
        return asin(tS*(1-x/C)*2/r/B*(1-EP))*r*r/2+tS*x/C;
    }
    else if(A>=r&&B<r){
        y=(cross(b,c,a)+sqrt(r*r*C*C-x_mult(b,c,a)*x_mult(b,c,a)))/C;
        tS=x_mult(a,b,c)/2;
        return asin(tS*(1-y/C)*2/r/A*(1-EP))*r*r/2+tS*y/C;
    }
    else if(fabs(x_mult(a,b,c))>=r*C||cross(b,c,a)<=0||cross(a,c,b)<=0){
        if(cross(a,b,c)<0)
            if(x_mult(a,b,c)<0)
                return (-acos(-1.0)-asin(x_mult(a,b,c)/A/B*(1-EP)))*r*r/2;
            else return (acos(-1.0)-asin(x_mult(a,b,c)/A/B*(1-EP)))*r*r/2;
        else return asin(x_mult(a,b,c)/A/B*(1-EP))*r*r/2;
    }
    else{
        x=(cross(a,c,b)+sqrt(r*r*C*C-x_mult(a,c,b)*x_mult(a,c,b)))/C;
        y=(cross(b,c,a)+sqrt(r*r*C*C-x_mult(b,c,a)*x_mult(b,c,a)))/C;
        tS=x_mult(a,b,c)/2;
        return (asin(tS*(1-x/C)*2/r/B*(1-EP))+asin(tS*(1-y/C)*2/r/A*(1-EP)))*r*r/2+tS*((y+x)/C-1);
    }
}

int main(){
    //freopen("1.txt", "r", stdin);
    Point p[105],cir;
    double r,area, x0, y0, v, angle, t, g;
    int i, n;
    while(scanf("%lf%lf%lf%lf%lf%lf%lf", &x0, &y0, &v, &angle, &t, &g, &r)!=EOF){
        if(fabs(x0)+fabs(y0)+fabs(v)+fabs(angle)+fabs(t)+fabs(g)+
           fabs(r)<0.0000001)break;
        scanf("%d", &n);
        for(i=0; i<n; i++)
        scanf("%lf%lf", &p[i].x, &p[i].y);
        area=0;cir.x=x0+v*cos(angle/180.0*Pi)*t;
        cir.y=y0+v*sin(angle/180.0*Pi)*t-0.5*g*t*t;
        for(i=0;i<n;i++){
            area+=cal_area(p[i], p[(i+1)%n], cir, r);
        }
        printf("%.2f\n",fabs(area));
    }
    return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值