UVALive 5075 Intersection of Two Prisms(柱体体积交)
题意:给出两个柱体,一个平行于z轴,设这个截面为A,在XOY面,一个平行于y轴,设这个截面为B,在XOZ面。求两个柱体的公共体积大小。
思路:我们用平行于YOZ的面去切这个公共 体积,因为所有数字为整数,我们可以在x方向每隔1切一次,这样就切成了一些长度为1的窄条,设[i-1,i]的这个窄条在i-1处在z方向的长度为 z[i-1],在y方向的长度为y[i-1],同理i处为z[i]和y[i]。z[i]其实就是B在x=i时上下两个z之差,y[i]就是A在x=i时两 个y之差。如下图:
我们令a=y[i]-y[i-1],b=y[i-1],c=z[i]-z[i-1],d=z[i-1],那么y对x在这个长度为1上的变化方程就是y=ax+b,同理z为z=cx+d,0<=x<=1,那么体积为:
int sgn(double x) { if(x>EPS) return 1; if(x<-EPS) return -1; return 0; } struct POINT { int x,y; POINT(){} POINT(int _x,int _y) { x=_x; y=_y; } void get() { RD(x,y); } }; struct point { double x,y; point(){} point(double _x,double _y) { x=_x; y=_y; } void get() { RD(x); RD(y); } point operator+(point a) { return point(x+a.x,y+a.y); } point operator-(point a) { return point(x-a.x,y-a.y); } double operator*(point a) { return x*a.y-y*a.x; } point operator*(double t) { return point(x*t,y*t); } double operator^(point a) { return x*a.x+y*a.y; } double len() { return sqrt(x*x+y*y); } point zhuanShun(double t) { return point(x*cos(t)+y*sin(t),y*cos(t)-x*sin(t)); } point zhuanNi(double t) { return point(x*cos(t)-y*sin(t),x*sin(t)+y*cos(t)); } point adjust(double L) { double d=len(); L/=d; return point(x*L,y*L); } void print() { printf("%.3lf %.3lf\n",x+EPS,y+EPS); } }; double len(point a) { return a.len(); } struct point3 { double x,y,z; point3(){} point3(double _x,double _y,double _z) { x=_x; y=_y; z=_z; } void get() { cin>>x>>y>>z; } point3 operator+(point3 a) { return point3(x+a.x,y+a.y,z+a.z); } point3 operator-(point3 a) { return point3(x-a.x,y-a.y,z-a.z); } point3 operator*(point3 a) { return point3(y*a.z-z*a.y,z*a.x-x*a.z,x*a.y-y*a.x); } point3 operator*(double t) { return point3(x*t,y*t,z*t); } double operator^(point3 a) { return x*a.x+y*a.y+z*a.z; } point3 operator/(double t) { return point3(x/t,y/t,z/t); } double len() { return sqrt(x*x+y*y+z*z); } point3 adjust(double L) { double t=len(); L/=t; return point3(x*L,y*L,z*L); } void print() { printf("%.10lf %.10lf %.10lf\n",x+EPS,y+EPS,z+EPS); } }; double len(point3 a) { return a.len(); } double getArea(point3 a,point3 b,point3 c) { double x=len((b-a)*(c-a)); return x/2; } double getVolume(point3 a,point3 b,point3 c,point3 d) { double x=(b-a)*(c-a)^(d-a); return x/6; } point3 pShadowOnPlane(point3 p,point3 a,point3 b,point3 c) { point3 v=(b-a)*(c-a); if(sgn(v^(a-p))<0) v=v*-1; v=v.adjust(1); double d=fabs(v^(a-p)); return p+v*d; } double lineToLine(point3 a,point3 b,point3 p,point3 q) { point3 v=(b-a)*(q-p); return fabs((a-p)^v)/len(v); } int pInPlane(point3 p,point3 a,point3 b,point3 c) { double S=getArea(a,b,c); double S1=getArea(a,b,p); double S2=getArea(a,c,p); double S3=getArea(b,c,p); return sgn(S-S1-S2-S3)==0; } int opposite(point3 p,point3 q,point3 a,point3 b,point3 c) { point3 v=(b-a)*(c-a); double x=v^(p-a); double y=v^(q-a); return sgn(x*y)<0; } int segCrossTri(point3 p,point3 q,point3 a,point3 b,point3 c) { return opposite(p,q,a,b,c)&& opposite(a,b,p,q,c)&& opposite(a,c,p,q,b)&& opposite(b,c,p,q,a); } double pToPlane(point3 p,point3 a,point3 b,point3 c) { double v=((b-a)*(c-a)^(p-a))/6; double s=len((b-a)*(c-a))/2; return fabs(3*v/s); } double pToLine(point3 p,point3 a,point3 b) { double S=len((a-p)*(b-p)); return S/len(a-b); } double pToSeg(point3 p,point3 a,point3 b) { if(sgn((p-a)^(b-a))<=0) return len(a-p); if(sgn((p-b)^(a-b))<=0) return len(b-p); return pToLine(p,a,b); } double pToPlane1(point3 p,point3 a,point3 b,point3 c) { point3 k=pShadowOnPlane(p,a,b,c); if(pInPlane(k,a,b,c)) return pToPlane(p,a,b,c); double x=pToSeg(p,a,b); double y=pToSeg(p,a,c); double z=pToSeg(p,b,c); return min(x,min(y,z)); } double getAng(point3 a,point3 b) { double x=(a^b)/len(a)/len(b); return acos(x); } double segToSeg(point3 a,point3 b,point3 p,point3 q) { point3 v=(b-a)*(q-p); double A,B,A1,B1; A=((b-a)*v)^(p-a); B=((b-a)*v)^(q-a); A1=((p-q)*v)^(a-q); B1=((p-q)*v)^(b-q); if(sgn(A*B)<=0&&sgn(A1*B1)<=0) { return lineToLine(a,b,p,q); } double x=min(pToSeg(a,p,q),pToSeg(b,p,q)); double y=min(pToSeg(p,a,b),pToSeg(q,a,b)); return min(x,y); } struct face { int a,b,c,ok; face(){} face(int _a,int _b,int _c,int _ok) { a=_a; b=_b; c=_c; ok=_ok; } }; struct _3DCH { face F[N<<2]; int b[N][N],cnt,n; point3 p[N]; int getDir(point3 t,face F) { double x=(p[F.b]-p[F.a])*(p[F.c]-p[F.a])^(t-p[F.a]); return sgn(x); } void deal(int i,int x,int y) { int f=b[x][y]; if(!F[f].ok) return; if(getDir(p[i],F[f])==1) DFS(i,f); else { b[y][x]=b[x][i]=b[i][y]=cnt; F[cnt++]=face(y,x,i,1); } } void DFS(int i,int j) { F[j].ok=0; deal(i,F[j].b,F[j].a); deal(i,F[j].c,F[j].b); deal(i,F[j].a,F[j].c); } void construct() { int i,j,k=0; for(i=1;i<n;i++) if(sgn(len(p[i]-p[0]))) { swap(p[i],p[1]); k++; break; } if(k!=1) return; for(i=2;i<n;i++) if(sgn(getArea(p[0],p[1],p[i]))) { swap(p[i],p[2]); k++; break; } if(k!=2) return; for(i=3;i<n;i++) if(sgn(getVolume(p[0],p[1],p[2],p[i]))) { swap(p[i],p[3]); k++; break; } if(k!=3) return; cnt=0; FOR0(i,4) { face k=face((i+1)%4,(i+2)%4,(i+3)%4,1); if(getDir(p[i],k)==1) swap(k.b,k.c); b[k.a][k.b]=b[k.b][k.c]=b[k.c][k.a]=cnt; F[cnt++]=k; } for(i=4;i<n;i++) FOR0(j,cnt) { if(F[j].ok&&getDir(p[i],F[j])==1) { DFS(i,j); break; } } j=0; FOR0(i,cnt) if(F[i].ok) F[j++]=F[i]; cnt=j; } point3 getCenter() { point3 ans=point3(0,0,0),o=point3(0,0,0); double s=0,temp; int i; FOR0(i,cnt) { face k=F[i]; temp=getVolume(o,p[k.a],p[k.b],p[k.c]); ans=ans+(o+p[k.a]+p[k.b]+p[k.c])/4*temp; s+=temp; } ans=ans/s; return ans; } double getMinDis(point3 a) { double ans=dinf; int i; FOR0(i,cnt) { face k=F[i]; ans=min(ans,pToPlane(a,p[k.a],p[k.b],p[k.c])); } return ans; } }; POINT a[N],b[N]; double YMin[N],YMax[N],ZMin[N],ZMax[N]; int n,m; void init(POINT a[],int n,double Min[],double Max[]) { a[n+1]=a[1]; int i,j; POINT p,q; double k,b; FOR1(i,n) { p=a[i]; q=a[i+1]; if(p.x>q.x) swap(p,q); Min[p.x]=min(Min[p.x],1.0*p.y); Max[p.x]=max(Max[p.x],1.0*p.y); if(p.x==q.x) continue; k=1.0*(p.y-q.y)/(p.x-q.x); b=p.y; for(j=p.x+1;j<=q.x;j++) { b+=k; Min[j]=min(Min[j],b); Max[j]=max(Max[j],b); } } } int main() { Rush(n) { RD(m); if(!n&&!m) break; int i; int xMin1=INF,xMax1=-INF,xMin2=INF,xMax2=-INF; FOR1(i,n) { a[i].get(); a[i].x+=100; xMin1=min(xMin1,a[i].x); xMax1=max(xMax1,a[i].x); } FOR1(i,m) { b[i].get(); b[i].x+=100; xMin2=min(xMin2,b[i].x); xMax2=max(xMax2,b[i].x); } FOR0(i,N) YMin[i]=ZMin[i]=dinf,YMax[i]=ZMax[i]=-dinf; init(a,n,YMin,YMax); init(b,m,ZMin,ZMax); double y[N],z[N]; int s=max(xMin1,xMin2); int e=min(xMax1,xMax2); for(i=s;i<=e;i++) { y[i]=YMax[i]-YMin[i]; z[i]=ZMax[i]-ZMin[i]; } double ans=0,A,B,C,D; for(i=s+1;i<=e;i++) { A=y[i]-y[i-1]; B=y[i-1]; C=z[i]-z[i-1]; D=z[i-1]; ans+=fabs(A*C/3+(A*D+B*C)/2+B*D); } PR(ans); } }
UVALive 5075 Intersection of Two Prisms(柱体体积交)的更多相关文章
- Intersection of Two Prisms(AOJ 1313)
原题如下: Suppose that P1 is an infinite-height prism whose axis is parallel to the z-axis, and P2 is al ...
- hdu3255扫描线:带权面积交转体积交
手贱把i打成j,调了半天 /* 面积并转体积并,长方体高度为作物价格 算体积并:在笛卡尔坐标系的y轴上建立线段树cnt记录区间被完全覆盖的次数,sum记录区间被覆盖的总长度 以平行于xoy的平面从下往 ...
- hdu 5120 Intersection 两个圆的面积交
Intersection Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) P ...
- Get The Treasury HDU - 3642(扫描线求三维面积交。。体积交)
题意: ...就是求体积交... 解析: 把每一层z抽出来,计算面积交, 然后加起来即可..! 去看一下 二维面积交的代码 再看看这个三维面积交的代码.. down函数里 你发现了什么规律!!! 参考 ...
- OpenCV图像处理与视频分析详解
1.OpenCV4环境搭建 VS2017新建一个控制台项目 配置包含目录 配置库目录 配置链接器 配置环境变量 重新启动VS2017 2.第一个图像显示程序 main.cpp #include< ...
- (转)看穿机器学习(W-GAN模型)的黑箱
本文转自:http://www.360doc.com/content/17/0212/11/35919193_628410589.shtml# 看穿机器学习(W-GAN模型)的黑箱 201 ...
- java 第九次作业
一.题目:利用接口和接口回调,实现简单工厂模式,当输入不同的字符,代表相应图形时,利用工厂类获得图形对象,再计算以该图形为底的柱体体积. 二.代码 /* 5个形状类分别调用Shape接口: 柱体类中, ...
- 黄杉杉 --java第七次作业
题目1:创建一个柱体类,包含矩形对象.高和体积等三个成员变量,一个构造方法进行成员变量初始化,和计算体积.换底两个功能方法,在主类中输入长.宽.高,计算柱体体积,输入新的长.宽.高,创建新的矩形对象, ...
- Java 接口及接口回调_Chris
题目: 利用接口和接口回调,实现简单工厂模式,当输入不同的字符,代表相应图形时,利用工厂类获得图形对象,再计算以该图形为底的柱体体积. 代码: 1.Test.java /** * 测试类,包含一个主方 ...
随机推荐
- oracle表分区
注:新建分区表前要先准备好要用的表空间 一. oracle分区类型: 范围分区(Range分区) 列表分区(List分区) 散列分区(Hash分区) 组合分区(Composite Partitioni ...
- nginx for windows中的一项缺陷
按照官网上的说法,使用 start nginx 启动 nginx,使用 nginx -s quit 可以优雅地退出. 经实验,使用 start nginx 之后,会启动两个 nginx 的进程,据官网 ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON EdgesImage
zw版[转发·台湾nvp系列Delphi例程]HALCON EdgesImage procedure TForm1.Button1Click(Sender: TObject);var img0, im ...
- android之费电检查 BetterBatteryStats
今天老大给了一个任务,是说我们的应用在后台时,还会比较费电!让我查一下 我立马头大了!无从下手! 一.赶紧百度,得到以下几个信息: ①费电的操作有:大数据量的传输;不停的在网络间切换;解析大量的文本数 ...
- ApkDec android反编译工具
转自:http://www.newasp.net/soft/70498.html 下载 ApkDec是一款免费的绿色APK反编译工具 forandroid ,由android开发者社区开发. ApkD ...
- 三层架构中bll层把datatable转换为实体model的理解
看了很多人的项目,很多都是用到三层架构,其中BLL层中有一种将DataTable转换为实体的方法.一直没有明白为啥要这样做,今天特意去搜索了一下,如果没有答案我是准备提问,寻求解答了.还好找到一个相关 ...
- 第一轮复习Servlet day04
* 数据的传送接收:后台通过request发送:req.setAttribute("emps", list); req.getRequestDispatcher("emp ...
- React笔记_(2)_react语法1
这一节内容主要以了解为主. 渐渐的体会react的语法和其特性. ① htmlAndJs 混合编写 react和以往的前后台书写方式不一样. 在之前的多个语言中,讲求的是将页面代码和js代码逻辑分开, ...
- android 常用命令
1.查看当前手机界面的 Activity dumpsys | grep "mFocusedActivity" 查看任务栈 dumpsys | grep "Hist&q ...
- Unix/Linux编程实践教程(二:socket、多线程、进程间通信)
同一接口不同的数据源: 协同进程: fdopen以文件描述符为参数: fopen和popen: 为了实现popen,必须在子进程中调用sh,因为只有shell本身即/bin/sh可以运行任意shell ...