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 /** * 测试类,包含一个主方 ...
 
随机推荐
- 系统配置SQL   profile
			
select M.RESPONSIBILITY_NAME, B.PROFILE_OPTION_NAME, X.USER_PROFILE_OPTION_NAME, t.profile_option_va ...
 - Concurrent Assertion
			
Concurrent assertion中要求必须有clock,从而保证在每个clock edge都进行触发判断. assertion与design进行同步执行,concurrent assert只能 ...
 - JSP-08-第三方控件的使用
			
添加图片 下载 commons-fileupload-1.2.2.jar和commons-io-2.4.jar 导入项目 在添加涂抹的页面设置表单属性 enctype=”multipart/form ...
 - zw版【转发·台湾nvp系列例程】HALCON MirrorRegion (Delphi)
			
zw版[转发·台湾nvp系列例程]HALCON MirrorRegion (Delphi) procedure TForm1.Button1Click(Sender: TObject);var img ...
 - 打开了chrome审查元素 发现报错 Uncaught SyntaxError: Unexpected token )
			
这个错误并不影响业务处理,但是看到有报错,心里总是不爽. 经过几番查找,发现了原因. <a href="javascript:void()" oncick="onS ...
 - Selenium 新手入门(C#)1. 用vs运行调用Selenium打开页面
			
Start步骤: 1.从http://docs.seleniumhq.org/download/ 下载 C# dll 文件和 Internet Explorer Driver Server(32 或 ...
 - SQL UNION 操作符
			
转由http://www.w3school.com.cn/sql/sql_union.asp 这个网址的数据库知识,个人推荐,因为有实例,理解更透彻一些.非广告啊,个人感觉好啊 SQL UNION 操 ...
 - gerrit
			
https://en.wikibooks.org/wiki/Git/Gerrit_Code_Review http://openwares.net/linux/gerrit2_setup.html 不 ...
 - 去除冗余 – 精简您的CSS样式代码
			
讲讲常见的一些没有必要使用CSS代码情况,而这些不起作用可以去掉的CSS代码可能是我们经常忽视的.越是对CSS理解不够,越容易出现这些问题. 二.一些常见不必要CSS样式 1.与默认CSS样式一致 我 ...
 - SQL SERVER 2008 中三种分页方法与总结
			
建立表: CREATE TABLE [TestTable] ( , ) NOT NULL , ) COLLATE Chinese_PRC_CI_AS NULL , ) COLLATE Chinese_ ...