POJ 3528 Ultimate Weapon(三维凸包表面积)

题目链接:http://poj.org/problem?id=3528

题意:求三维凸包表面积。

思路:模板。





struct Point

{

    double x,y,z;



    Point() {}

    Point(double _x,double _y,double _z)

	{

		x=_x;

		y=_y;

		z=_z;

	}



	void Get()

	{

	    RD(x,y,z);

	}

    Point operator-(const Point p1)

	{

		return Point(x-p1.x,y-p1.y,z-p1.z);

	}



    Point operator*(Point p)

	{

		return Point(y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x);

	}

    double operator^(Point p)

	{

		return x*p.x+y*p.y+z*p.z;

	}



	double len()

	{

	    return sqrt(sqr(x)+sqr(y)+sqr(z));

	}

};



struct _3DCH

{

    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;

        }

    }F[N<<2];

    int n,cnt,b[N][N];

    Point p[N];



    int DB(double x)

    {

        if(x>1e-10) return 1;

        if(x<-1e-10) return -1;

        return 0;

    }



    double vlen(Point a)

    {

        return a.len();

    }



    double getArea(Point a,Point b,Point c)

    {

        return vlen((b-a)*(c-a));

    }



    double getVolume(Point a,Point b,Point c,Point d)

    {

        return (b-a)*(c-a)^(d-a);

    }



    //t在f的正面返回1,反面返回-1,在f上返回0

    int getDir(Point t,face f)

    {

        double x=(p[f.b]-p[f.a])*(p[f.c]-p[f.a])^(t-p[f.a]);

        return DB(x);

    }



    void deal(int i,int x,int y)

    {

        int f=b[x][y];

        face temp;

        if(!F[f].ok) return;

        if(getDir(p[i],F[f])>0) DFS(i,f);

        else

        {

            temp=face(y,x,i,1);

            b[y][x]=b[x][i]=b[i][y]=cnt;

            F[cnt++]=temp;

        }

    }



    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()

    {

        if(n<4) return;

        int i,j,k=0;

        FOR1(i,n-1) if(DB(vlen(p[0]-p[i])))

        {

            swap(p[1],p[i]);

            k=1;

            break;

        }

        if(!k) return;

        k=0;

        FOR(i,2,n-1) if(DB(getArea(p[0],p[1],p[i])))

        {

            swap(p[2],p[i]);

            k=1;

            break;

        }

        if(!k) return;;

        k=0;

        FOR(i,3,n-1) if(DB(getVolume(p[0],p[1],p[2],p[i])))

        {

            swap(p[3],p[i]);

            k=1;

            break;

        }

        if(!k) return;



        cnt=0;

        face temp;

        FOR0(i,4)

        {

            temp=face((i+1)%4,(i+2)%4,(i+3)%4,1);

            if(getDir(p[i],temp)>0) swap(temp.b,temp.c);

            b[temp.a][temp.b]=b[temp.b][temp.c]=b[temp.c][temp.a]=cnt;

            F[cnt++]=temp;

        }



        FOR(i,4,n-1) FOR0(j,cnt) if(F[j].ok&&getDir(p[i],F[j])>0)

        {

            DFS(i,j);

            break;

        }

        j=0;

        FOR0(i,cnt) if(F[i].ok) F[j++]=F[i];

        cnt=j;

    }



    double getSumArea()

    {

        double ans=0;

        int i;

        FOR0(i,cnt) ans+=getArea(p[F[i].a],p[F[i].b],p[F[i].c]);

        return ans/2;

    }

};



_3DCH a;



int main()

{

    while(scanf("%d",&a.n)!=-1)

    {

        int i;

        FOR0(i,a.n) a.p[i].Get();

        a.construct();

        double s=a.getSumArea();

        printf("%.3lf\n",s);

    }

    return 0;

}

  

你可能感兴趣的:(poj)