• CF717I Cowboy Beblop at his computer


    Link
    (poly_i(iin{0,1}))(n_i)个顶点,按顺序为(a_{i,0},cdots,a_{i,n_i}(a_{i,n_i}=a_{i,0})),法向量为(vec{p_i}),所在平面为(flat_i)

    step.1

    计算出(vec x=vec{p_0} imesvec{p_1}),这是(l=flat_0cap flat_1)的方向。
    如果(|vec x|=0)那么(flat_0parallel flat_1)

    step.2

    考虑计算(poly_0)的边与(flat_1)的交点及方向。
    可以用(o_{0,i}=operatorname{sgn}(cos<overrightarrow{a_{0,i}-a_{1,0}},vec{p_1}>)=operatorname{sgn}(overrightarrow{a_{0,i}-a_{1,0}}cdotvec{p_1}))表示(a_{0,j})(flat_1)的位置关系。
    (o_{0,i}=egin{cases}1& ext{above}\0& ext{on}\-1& ext{below}end{cases})
    那么(e_{0,i}=o_{0,i}-o_{0,i+1})就可以表示(operatorname{seg}(a_{0,i},a_{0,i+1}))(flat_1)的位置关系。
    (|e_{0,i}|=egin{cases}2& ext{intersect}\1& ext{tangent}\0& ext{apart}end{cases})
    (operatorname{sgn}(e_{0,i})=egin{cases}1& ext{down}\0& ext{apart}\-1& ext{up}end{cases})
    对于(e_{0,i} e0),计算得到(operatorname{seg}(a_{0,i},a_{0,i+1})cap flat_1=y_{0,i}=a_{0,i}+frac{overrightarrow{a_{0,i}-a_{1,0}cdot}vec{p_1}}{overrightarrow{a_{0,i}-a_{1,0}}cdotvec{p_1}}overrightarrow{a_{0,i+1}-a_{0,i}})

    同理求出所有(e_{1,i},y_{1,i}(e_{1,i} e0))

    step.3

    很显然所有(y_{t,i})都在(l)上,且因为相切的交点计算了两次,所以两个多边形与(l)的交点个数都是偶数。
    计算出(y_{t,i})按在(vec x)方向上的坐标(pos_{t,i}=vec{y_{t,i}} imesvec x)
    那么([y_{0,i}in poly_1]=|sumlimits_{pos_{1,j}<pos_{0,i}}e_{1,j}|)

    这样我们就成功地判断了(y_{0,i})(poly_1)的位置关系,结合(e_{0,i})即可算出(poly_0)从上往下和从下往上穿过(poly_1)的次数。

    app.

    如何得到(y_{t,i})的计算式?
    (y_{0,i}=a_{0,i}+k_ioverrightarrow{a_{0,i+1}-a_{0,i}}),则(overrightarrow{y_{0,i}-a_{1,0}}=overrightarrow{a_{0,i}-a_{1,0}}+k_ioverrightarrow{a_{0,i+1}-a_{0,i}})
    两边同时对(vec{p_1})点积得到(k_i=frac{overrightarrow{a_{0,i}-a_{1,0}cdot}vec{p_1}}{overrightarrow{a_{0,i}-a_{1,0}}cdotvec{p_1}})
    (y_{1,i})同理。

    #include<cstdio>
    #include<vector>
    #include<utility>
    #include<algorithm>
    using std::pair;
    using db=long double;
    using i64=long long;
    const int N=100007;
    struct vec{i64 x,y,z;}a[2][N],p[2],x;
    vec operator-(const vec&a,const vec&b){return {a.x-b.x,a.y-b.y,a.z-b.z};}
    vec operator*(const vec&a,const vec&b){return {a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x};}
    i64 operator^(const vec&a,const vec&b){return a.x*b.x+a.y*b.y+a.z*b.z;}
    int n[2],o[N],s,t;
    std::vector<pair<db,pair<int,int>>>vec;
    int read(){int x;scanf("%d",&x);return x;}
    int sgn(i64 x){return x<0? -1:x? 1:0;}
    int main()
    {
        for(int t=0;t<2;++t)
        {
    	n[t]=read();
    	for(int i=0;i<n[t];++i) a[t][i]={read(),read(),read()};
    	a[t][n[t]]=a[t][0],p[t]=(a[t][1]-a[t][0])*(a[t][2]-a[t][0]);
        }
        if(x=p[0]*p[1],!(x^x)) return !puts("NO");
        for(int t=0;t<2;++t)
        {
    	for(int i=0;i<=n[t];++i) o[i]=sgn((a[t][i]-a[t^1][0])^p[t^1]);
    	for(int i=0;i<n[t];++i)
    	    if(o[i]^o[i+1])
    		vec.push_back({(a[t][i]^x)+((a[t][i+1]-a[t][i])^x)*(db)(p[t^1]^(a[t][i]-a[t^1][0]))/(p[t^1]^(a[t][i]-a[t][i+1])),{t,o[i]-o[i+1]}});
        }
        std::sort(vec.begin(),vec.end());
        for(auto x:vec) x.second.first? s+=t*x.second.second:t+=x.second.second;
        puts(s? "YES":"NO");
    }
    
  • 相关阅读:
    第一课基础知识
    Linux基础命令
    IO&Process基础知识
    caffe-windows 运行matlab 接口的例子
    process 3d image using caffe
    caffe-windows配置 cuda6.5+vs2012
    cuda7.0安装windows+vs2012
    SGD步长
    Exercise: Convolutional Neural NetworkCNN的反向求导及练习
    Create sparse matrix:sparse
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12357143.html
Copyright © 2020-2023  润新知