• 原题如下:

    Suppose that P1 is an infinite-height prism whose axis is parallel to the z-axis, and P2 is also an infinite-height prism whose axis is parallel to the y-axis. P1 is defined by the polygon C1 which is the cross section of P1 and the xy-plane, and P2is also defined by the polygon C2 which is the cross section of P2 and the xz-plane.

    Figure I.1 shows two cross sections which appear as the first dataset in the sample input, and Figure I.2 shows the relationship between the prisms and their cross sections.

    Figure I.1: Cross sections of Prisms

    Figure I.2: Prisms and their cross sections

    Figure I.3: Intersection of two prisms

    Figure I.3 shows the intersection of two prisms in Figure I.2, namely, P1 and P2.

    Write a program which calculates the volume of the intersection of two prisms.

    Input

    The input is a sequence of datasets. The number of datasets is less than 200.

    Each dataset is formatted as follows.

    m n
    x11 y11
    x12 y12 
    .
    .
    .
    x1m y1m 
    x21 z21
    x22 z22
    .
    .
    .
    x2n z2n

    m and n are integers (3 ≤ m ≤ 100, 3 ≤ n ≤ 100) which represent the numbers of the vertices of the polygons, C1 and C2, respectively.

    x1iy 1 ix 2j and z 2j are integers between -100 and 100, inclusive. ( x 1iy 1i) and ( x 2j , z 2j) mean the i-th and j-th vertices' positions of C 1 and C 2respectively.

    The sequences of these vertex positions are given in the counterclockwise order either on the xy-plane or the xz-plane as in Figure I.1.

    You may assume that all the polygons are convex, that is, all the interior angles of the polygons are less than 180 degrees. You may also assume that all the polygons are simple, that is, each polygon's boundary does not cross nor touch itself.

    The end of the input is indicated by a line containing two zeros.

    Output

    For each dataset, output the volume of the intersection of the two prisms, P1 and P2, with a decimal representation in a line.

    None of the output values may have an error greater than 0.001. The output should not contain any other extra characters.

    Sample Input

    4 3
    7 2
    3 3
    0 2
    3 1
    4 2
    0 1
    8 1
    4 4
    30 2
    30 12
    2 12
    2 2
    15 2
    30 8
    13 14
    2 8
    8 5
    13 5
    21 7
    21 9
    18 15
    11 15
    6 10
    6 8
    8 5
    10 12
    5 9
    15 6
    20 10
    18 12
    3 3
    5 5
    10 3
    10 10
    20 8
    10 15
    10 8
    4 4
    -98 99
    -99 -99
    99 -98
    99 97
    -99 99
    -98 -98
    99 -99
    96 99
    0 0

    Output for the Sample Input

    4.708333333333333
    1680.0000000000005
    491.1500000000007
    0.0
    7600258.4847715655
  • 题解:朴素想法,求出公共部分的凸多面体的顶点坐标,然后再计算其体积。公共部分的凸多面体的顶点都是一个棱柱的侧面与另一个棱柱的侧棱的交点,可以通过O(nm)时间的枚举求得,但因为涉及三维空间的几何运算,实现起来是非常麻烦的。
    事实上,沿x轴对棱柱切片即可:按某个值对侧棱与z轴平行的棱柱P1切片后,就得到了[y1,y2]*(-∞,∞)这样的在z轴方向无限延伸的长方形的横截面,同样的,我们按某个x值对侧棱与y轴平行的棱柱P2切片后,就得到了(-∞,∞)*[z1,z2]这样的在y轴方向无限延伸的长方形的横截面。因此,我们按某个x值对两个棱柱的公共部分切片后,得到的横截面就是长方形[y1,y2]*[z1,z2]。而长方形的面积通过(y2-y1)*(z2-z1)就可以求得,关于x轴对面积求积分就能得到公共部分的体积了。
    首先,枚举出原棱柱底面顶点的所有x坐标并排序,在相邻两个x坐标之间的区间中按x值切片得到的长方形的顶点坐标是关于x的线性函数,所以面积就是关于x的二次函数,其积分很容易计算,虽然可以通过求得表达式后再来计算二次函数的积分,但应用Simpson公式则更为轻松。Simpson公式如下:

    Simpson公式就是在数值积分中用二次函数来近似原函数进行积分而得到的公式,如果原函数本身就是次数不超过二的多项式,那么用Simpson公式就可以得到精确的积分值。利用该公式,无需求出关于x的多项式,而只要计算按区间的端点和中点切片得到的长方形的面积就够了。

  • 代码:
    #include<cstdio>
    #include<algorithm>
    #include<vector> using namespace std; const int INF=0x3f3f3f3f;
    const double EPS=1e-;
    const int MAX_N=;
    int N,M;
    int X1[MAX_N], Y1[MAX_N], X2[MAX_N], Z2[MAX_N]; double max(double x, double y)
    {
    if (x>y+EPS) return x;
    return y;
    } double min(double x, double y)
    {
    if (x<y-EPS) return x;
    return y;
    } double width(int * X, int * Y, int n, double x)
    {
    double lb=INF, ub=-INF;
    for (int i=; i<n; i++)
    {
    double x1=X[i], y1=Y[i], x2=X[(i+)%n], y2=Y[(i+)%n];
    if ((x1-x)*(x2-x)<= && 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);
    } int main()
    {
    while (~scanf("%d %d", &M, &N))
    {
    if (M== && N==) break;
    for (int i=; i<M; i++)
    {
    scanf("%d %d", &X1[i], &Y1[i]);
    }
    for (int i=; i<N; i++)
    {
    scanf("%d %d", &X2[i], &Z2[i]);
    }
    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=; i<M; i++) xs.push_back(X1[i]);
    for (int i=; i<N; i++) xs.push_back(X2[i]);
    sort(xs.begin(), xs.end());
    double res=;
    for (int i=; i+<xs.size(); i++)
    {
    double a=xs[i], b=xs[i+], c=(a+b)/;
    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)/*(fa+*fc+fb);
    }
    }
    printf("%.10f\n", res);
    }
    }

Intersection of Two Prisms(AOJ 1313)的更多相关文章

  1. UVALive 5075 Intersection of Two Prisms(柱体体积交)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  2. [LeetCode] Intersection of Two Arrays II 两个数组相交之二

    Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...

  3. [LeetCode] Intersection of Two Arrays 两个数组相交

    Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...

  4. [LeetCode] Intersection of Two Linked Lists 求两个链表的交点

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

  5. 【leetcode】Intersection of Two Linked Lists

    题目简述: Write a program to find the node at which the intersection of two singly linked lists begins. ...

  6. AOJ 0121: Seven Puzzle【BFS】

    From: AOJ 0121 思路:与前几题的bfs不同,这次的bfs没有明确的移动对象,看似任意一个数都可以当成对象移动.这时我们只需要抓住一个格子就行,比如我们把0作为移动对象,那么0在地图中漫游 ...

  7. [LintCode] Intersection of Two Linked Lists 求两个链表的交点

    Write a program to find the node at which the intersection of two singly linked lists begins. Notice ...

  8. LeetCode Intersection of Two Arrays

    原题链接在这里:https://leetcode.com/problems/intersection-of-two-arrays/ 题目: Given two arrays, write a func ...

  9. AOJ DSL_2_C Range Search (kD Tree)

    Range Search (kD Tree) The range search problem consists of a set of attributed records S to determi ...

随机推荐

  1. CSS动画实例:一颗躁动的心

    在页面中放置一个类名为container的层作为盛放心心的容器,在该层中再定义一个名为heart的子层,HTML代码描述如下: <div class="container"& ...

  2. Dubbo系列之 (四)服务订阅(1)

    辅助链接 Dubbo系列之 (一)SPI扩展 Dubbo系列之 (二)Registry注册中心-注册(1) Dubbo系列之 (三)Registry注册中心-注册(2) Dubbo系列之 (四)服务订 ...

  3. Jmeter 常用函数(6)- 详解 __P

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 和 __property 作用一样,不 ...

  4. github 加速方法

    登录网址:https://github.com.ipaddress.com/codeload.github.com#ipinfo 更改hosts:

  5. Robot Framework(8)——脚本语法示例记录

    大神写了一个Robot Framework的脚本,好多语法之前没接触过,就有了这篇,记录下来一起学习,欢迎纠错 第二三四五列,一般是入参,红色的表示必填的入参.浅灰色表示选填的入参.深灰色表示无需填写 ...

  6. 第4篇 Scrum 冲刺博客(专✌️团队)

    一.站立式会议 1.1会议图片 1.2成员完成情况 成员 昨天完成的任务 今天计划完成的任务 工作中的困难 陈忠明 按下载热度返回歌曲信息,与前端尝试交互 歌曲信息的上传/下载包 前后端交互问题 吴茂 ...

  7. ElementUI 不维护了?供我们选择的 Vue 组件库还有很多!

    前文回顾:Vue+Spring Boot 前后端分离的商城项目开源啦! Vue 组件千千万,只要不行咱就换. ElementUI 近况 根据我最近的观察,得知一些关于 ElementUI 维护人员都退 ...

  8. MD笔记

    1.力场中的例子电荷是有效电荷(clayff),有别于化学式中的电荷. 2.游离状态的阳离子(如层间阳离子)的电荷不能变动:而Al-O八面体.Si-O四面体中的离子(Al.Si等)电荷可以微调. 3. ...

  9. 【Spring】使用@Profile注解实现开发、测试和生产环境的配置和切换,看完这篇我彻底会了!!

    写在前面 在实际的企业开发环境中,往往都会将环境分为:开发环境.测试环境和生产环境,而每个环境基本上都是互相隔离的,也就是说,开发环境.测试环境和生产环境是互不相通的.在以前的开发过程中,如果开发人员 ...

  10. 温故知新——Spring AOP

    Spring AOP 面向切面编程,相信大家都不陌生,它和Spring IOC是Spring赖以成名的两个最基础的功能.在咱们平时的工作中,使用IOC的场景比较多,像咱们平时使用的@Controlle ...