Esempio n. 1
0
// Returns a rotation matrix whose third column is equal to the given vector.
Matrix3D Matrix3D::rotationMatrixFromZAxis(const Real3D& dir)
{
	// Normalize the target direction
	// If it is degenerate, returns the identity matrix
	Real3D target = dir;
	REAL len = target.mod();
	if (len == 0) return Matrix3D(1);
	target /= len;
	if (!target.isfinite()) return Matrix3D(1);
	// Find a non-degenerate vector orthogonal to the target
	Real3D v1 = Real3D(1,0,0) ^ target;
	REAL l1 = v1.sqrmod();
	Real3D v2 = Real3D(0,1,0) ^ target;
	REAL l2 = v2.sqrmod();
	Real3D v3 = Real3D(0,0,1) ^ target;
	REAL l3 = v3.sqrmod();
	// Choose the largest among v1,v2,v3
	Real3D v;
	if (l1 >= l2 && l1 >= l3) v = v1.vers();
	else if (l2 >= l1 && l2 >= l3) v = v2.vers();
	else /* if (l3 >= l1 && l3 >= l2) */ v = v3.vers();
	// Build the rotation matrix
	Real3D w = (target^v).vers();
	Matrix3D rot;
	rot.setCols(v, w, target);
	// Debug Check
	assert(fabs(rot.det()-1) < Math::TOLERANCE);
	return rot;
}
Esempio n. 2
0
/// Returns a rotation matrix whose third column is equal to the given vector.
Matrix3D Matrix3D::rotationMatrixFromZAxisForDXF(const Real3D& dir)
{
	// Normalize the target direction
	// If it is degenerate, returns the identity matrix
	Real3D target = dir;
	REAL len = target.mod();
	if (len == 0) return Matrix3D(1);
	target /= len;
	if (!target.isfinite()) return Matrix3D(1);

	// Choice of xAxis: see AutoCAD documentation.
	Real3D v;
	if( fabs(target[0])*64 < 1 && fabs(target[1])*64 < 1 )
		v = Real3D(0,1,0) ^ target;
	else
		v = Real3D(0,0,1) ^ target;

	v = v.vers();
	Real3D w = (target^v).vers();
	Matrix3D rot;
	rot.setCols(v, w, target);
	// Debug Check
	assert(fabs(rot.det()-1) < Math::TOLERANCE);
	return rot;
}
Esempio n. 3
0
      // note that for theta=0 the force is set to 0, while the energy as function of theta has a cusp
      bool _computeForceRaw(Real3D& force12,
                            Real3D& force32,
			    const Real3D& dist12,
			    const Real3D& dist32) const {

      	const real SMALL_EPSILON = 1.0E-9;

        real dist12_sqr = dist12 * dist12;
        real dist32_sqr = dist32 * dist32;
        real dist12_magn = sqrt(dist12_sqr);
        real dist32_magn = sqrt(dist32_sqr);
        real a11, a12, a22;

        // theta is the angle between r_{12} and r_{32} 

        real cos_theta = dist12 * dist32 / (dist12_magn * dist32_magn);
        if(cos_theta < -1.0) cos_theta = -1.0;
        if(cos_theta >  1.0) cos_theta =  1.0;

        real sin_theta = sqrt(1.0 - cos_theta*cos_theta);
 
        a11 = cos_theta / dist12_sqr;
        a12 = -1.0 / (dist12_magn * dist32_magn);
        a22 =  cos_theta / dist32_sqr;

        if (sin_theta > SMALL_EPSILON) { //sin_theta is always positive
          force12 = (Kcos_theta0-Ksin_theta0*cos_theta/sin_theta)*(a11 * dist12 + a12 * dist32);
          force32 = (Kcos_theta0-Ksin_theta0*cos_theta/sin_theta)*(a22 * dist32 + a12 * dist12);}
        else {
          force12  = Real3D(0.0,0.0,0.0);
          force32  = Real3D(0.0,0.0,0.0);
        }

        
        return true;
      }