Intersection of Two Prisms Aizu - 1313 (Simpson积分)

传送门

题意:有一个侧棱与z轴平行的棱柱P1和一个侧棱与y轴平行的棱柱P2.它们都向两端无限延伸,底面分别是包含M个顶点和N个顶点的凸多边形,其中第i个顶点的坐标分别是(X1i,Y1i)和(X2i,Z2i)。请计算这两个棱柱公共部分的体积。

题解:使用Simpson积分做

 

附上代码:


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>

using namespace std;

const int MAX_N=150;
const double INF=99999;

int M,N;
int X1[MAX_N],Y1[MAX_N];
int X2[MAX_N],Z2[MAX_N];

double width(int *X,int *Y,int n,double x)
{
    double lb=INF,ub=-INF;
    for(int i=0;i<n;i++){
        double x1=X[i],y1=Y[i],x2=X[(i+1)%n],y2=Y[(i+1)%n];
        if((x1-x)*(x2-x)<=0&&x1!=x2){
            double y=y1+(y2-y1)*(x-x1)/(x2-x1);
            lb=min(lb,y);
            ub=max(ub,y);
        }
    }
    return max(0.0,ub-lb);
}

void solve()
{
    int min1=*min_element(X1,X1+M),max1=*max_element(X1,X1+M);
    int min2=*min_element(X2,X2+N),max2=*max_element(X2,X2+N);
    vector<int>xs;
    for(int i=0;i<M;i++){
        xs.push_back(X1[i]);
    }
    for(int i=0;i<N;i++){
        xs.push_back(X2[i]);
    }
    sort(xs.begin(),xs.end());
    double res=0;
    for(int i=0;i+1<xs.size();i++){
        double a=xs[i],b=xs[i+1],c=(a+b)/2;
        if(min1<=c&&c<=max1&&min2<=c&&c<=max2){
            double fa=width(X1,Y1,M,a)*width(X2,Z2,N,a);
            double fb=width(X1,Y1,M,b)*width(X2,Z2,N,b);
            double fc=width(X1,Y1,M,c)*width(X2,Z2,N,c);
            res+=(b-a)/6*(fa+4*fc+fb);
        }
    }
    printf("%.10f\n",res);
}

int main()
{
    while(scanf("%d%d",&M,&N)!=EOF){
        if(M==0&&N==0){
            break;
        }
        for(int i=0;i<M;i++){
            scanf("%d%d",&X1[i],&Y1[i]);
        }
        for(int i=0;i<N;i++){
            scanf("%d%d",&X2[i],&Z2[i]);
        }
        solve();
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值