示例#1
0
void ComputeSphere(Fsphere &B, FvectorVec& V)
{
    if (V.size()<3) 	{ B.P.set(0,0,0); B.R=0.f; return; }

	// 1: calc first variation
	Fsphere	S1;
    Fsphere_compute		(S1,V.begin(),V.size());
	BOOL B1				= SphereValid(V,S1);
    
	// 2: calc ordinary algorithm (2nd)
	Fsphere	S2;
	Fbox bbox;
    bbox.invalidate		();
	for (FvectorIt I=V.begin(); I!=V.end(); I++)	bbox.modify(*I);
	bbox.grow			(EPS_L);
	bbox.getsphere		(S2.P,S2.R);
	S2.R = -1;
	for (I=V.begin(); I!=V.end(); I++)	{
		float d = S2.P.distance_to_sqr(*I);
		if (d>S2.R) S2.R=d;
	}
	S2.R = _sqrt (_abs(S2.R));
	BOOL B2				= SphereValid(V,S2);

	// 3: calc magic-fm
	Mgc::Sphere _S3 = Mgc::MinSphere(V.size(), (const Mgc::Vector3*) V.begin());
	Fsphere	S3;
	S3.P.set			(_S3.Center().x,_S3.Center().y,_S3.Center().z);
	S3.R				= _S3.Radius();
	BOOL B3				= SphereValid(V,S3);

	// select best one
	if (B1 && (S1.R<S2.R)){		// miniball or FM
		if (B3 && (S3.R<S1.R)){ // FM wins
        	B.set	(S3);
		}else{					// MiniBall wins
        	B.set	(S1);
		}
	}else{						// base or FM
		if (B3 && (S3.R<S2.R)){	// FM wins
        	B.set	(S3);
		}else{					// Base wins :)
        	R_ASSERT(B2);
        	B.set	(S2);
		}
	}
}
示例#2
0
BOOL	SphereValid	(FvectorVec& geom, Fsphere& test)
{
	if (!f_valid(test.P.x) || !f_valid(test.R))	{
		Msg	("*** Attention ***: invalid sphere: %f,%f,%f - %f",test.P.x,test.P.y,test.P.z,test.R);
	}

	Fsphere	S	=	test;
	S.R			+=	EPS_L;
	for (FvectorIt I = geom.begin(); I!=geom.end(); I++)
		if (!S.contains(*I))	return FALSE;
	return TRUE;
}
示例#3
0
int AppendVertex(FvectorVec& _points, MPoint& _pt)
{
	Fvector pt; 
	// convert from internal units to the current ui units
	MDistance dst_x	(_pt.x);
	MDistance dst_y	(_pt.y);
	MDistance dst_z	(_pt.z);
	pt.set		((float)dst_x.asMeters(),(float)dst_y.asMeters(),-(float)dst_z.asMeters());

	for (FvectorIt it=_points.begin(); it!=_points.end(); it++)
		if (it->similar(pt)) return it-_points.begin();
	_points.push_back(pt);
	return _points.size()-1;
}
示例#4
0
void ComputeCylinder(Fcylinder& C, Fobb& B, FvectorVec& V)
{
    if (V.size()<3) 	{ C.invalidate(); return; }
    // pow(area,(3/2))/volume
    // 2*Pi*R*H+2*Pi*R*R
	
//	Fvector axis;
    float max_hI   	= flt_min;
    float min_hI   	= flt_max;
    float max_rI   	= flt_min;
    float max_hJ   	= flt_min;
    float min_hJ   	= flt_max;
    float max_rJ   	= flt_min;
    float max_hK   	= flt_min;
    float min_hK   	= flt_max;
    float max_rK   	= flt_min;
    Fvector axisJ 		= B.m_rotate.j;
    Fvector axisI 		= B.m_rotate.i;
    Fvector axisK 		= B.m_rotate.k;
    Fvector& c			= B.m_translate;
    for (FvectorIt I=V.begin(); I!=V.end(); I++){
        Fvector tmp;
    	Fvector pt		= *I;
    	Fvector pt_c;	pt_c.sub(pt,c);

    	float pI		= axisI.dotproduct(pt);
        min_hI			= _min(min_hI,pI);
        max_hI			= _max(max_hI,pI);
        tmp.mad			(c,axisI,axisI.dotproduct(pt_c));
        max_rI			= _max(max_rI,tmp.distance_to(pt));
        
    	float pJ		= axisJ.dotproduct(pt);
        min_hJ			= _min(min_hJ,pJ);
        max_hJ			= _max(max_hJ,pJ);
        tmp.mad			(c,axisJ,axisJ.dotproduct(pt_c));
        max_rJ			= _max(max_rJ,tmp.distance_to(pt));

    	float pK		= axisK.dotproduct(pt);
        min_hK			= _min(min_hK,pK);
        max_hK			= _max(max_hK,pK);
        tmp.mad			(c,axisK,axisK.dotproduct(pt_c));
        max_rK			= _max(max_rK,tmp.distance_to(pt));
    }

    float hI			= (max_hI-min_hI);
    float hJ			= (max_hJ-min_hJ);
    float hK			= (max_hK-min_hK);
    float vI			= hI*M_PI*_sqr(max_rI);
    float vJ			= hJ*M_PI*_sqr(max_rJ);
    float vK			= hK*M_PI*_sqr(max_rK);
//    vI					= pow(2*M_PI*max_rI*hI+2*M_PI*_sqr(max_rI),3/2)/vI;
//    vJ					= pow(2*M_PI*max_rJ*hJ+2*M_PI*_sqr(max_rJ),3/2)/vJ;
//    vK					= pow(2*M_PI*max_rK*hK+2*M_PI*_sqr(max_rK),3/2)/vK;
    // pow(area,(3/2))/volume
    // 2*Pi*R*H+2*Pi*R*R
    
    if (vI<vJ){
    	if (vI<vK){
        	//vI;
            C.m_direction.set	(axisI);
            C.m_height			= hI;
            C.m_radius			= max_rI;
        }else{
        	// vK
            C.m_direction.set	(axisK);
            C.m_height			= hK;
            C.m_radius			= max_rK;
        }
    }else {
        //vJ < vI
     	if (vJ<vK){
        	// vJ
            C.m_direction.set	(axisJ);
            C.m_height			= hJ;
            C.m_radius			= max_rJ;
        } else {
            //vK
            C.m_direction.set	(axisK);
            C.m_height			= hK;
            C.m_radius			= max_rK;
        }
    }
    
    C.m_center.set		(B.m_translate);
/*
    if (V.size()<3) { B.invalidate(); return; }
    Mgc::Cylinder CYL	= Mgc::ContCylinder(V.size(), (const Mgc::Vector3*) V.begin());
    B.m_center.set		(CYL.Center());
    B.m_direction.set	(CYL.Direction());
    B.m_height			= CYL.Height();
    B.m_radius			= CYL.Radius();
*/
}