예제 #1
0
Real ExtPlane3<Real>::IntersectRay( const Wml::Vector3<Real> & vOrigin,
								    const Wml::Vector3<Real> & vDirection ) const
{
	Wml::Vector3<Real> vN(this->Normal);
	Real fDenom = vDirection.Dot(vN);
	if ( fDenom == 0 )
		return std::numeric_limits<Real>::max();
	return (this->Constant - vOrigin.Dot(vN)) / fDenom; 
}
예제 #2
0
static void
simplifyDP( Real tol, std::vector<Wml::Vector3<Real> > & v, int j, int k, std::vector<bool> & mk )
{
    if (k <= j+1) // there is nothing to simplify
        return;

    // check for adequate approximation by segment S from v[j] to v[k]
    int     maxi = j;          // index of vertex farthest from S
    Real   maxd2 = 0;         // distance squared of farthest vertex
    Real   tol2 = tol * tol;  // tolerance squared
	Wml::Segment3<Real> S;    // segment from v[j] to v[k]
		S.Origin = v[j];
		S.Direction = v[k] - v[j];
		S.Extent = S.Direction.Normalize();
	Wml::Vector3<Real> u( S.Direction );  // segment direction vector
	Real cu = u.SquaredLength();            // segment length squared

    // test each vertex v[i] for max distance from S
    // compute using the Feb 2001 Algorithm's dist_Point_to_Segment()
    // Note: this works in any dimension (2D, 3D, ...)
	Wml::Vector3<Real> w;
	Wml::Vector3<Real> Pb;   // base of perpendicular from v[i] to S
	Real b, cw, dv2;         // dv2 = distance v[i] to S squared

    for (int i = j+1; i < k; i++)
    {
        // compute distance squared
		w = v[i] - S.Origin;
        cw = w.Dot(u);
        if ( cw <= 0 )
			dv2 = (v[i] - S.Origin).SquaredLength();
        else if ( cu <= cw )
			dv2 = (v[i] - (S.Origin + S.Direction)).SquaredLength();
        else {
            b = cw / cu;
            Pb = S.Origin + u * b;
			dv2 = (v[i] - Pb).SquaredLength();
        }
        // test with current max distance squared
        if (dv2 <= maxd2)
            continue;
        // v[i] is a new max vertex
        maxi = i;
        maxd2 = dv2;
    }
    if (maxd2 > tol2)        // error is worse than the tolerance
    {
        // split the polyline at the farthest vertex from S
        mk[maxi] = true;      // mark v[maxi] for the simplified polyline
        // recursively simplify the two subpolylines at v[maxi]
        simplifyDP( tol, v, j, maxi, mk );  // polyline v[j] to v[maxi]
        simplifyDP( tol, v, maxi, k, mk );  // polyline v[maxi] to v[k]
    }
    // else the approximation is OK, so ignore intermediate vertices
    return;
}
예제 #3
0
void Wml::StretchMetric1( const Vector3<Real> & q1, 
						 const Vector3<Real> & q2,
						 const Vector3<Real> & q3,
						 const Vector2<Real> & p1,
						 const Vector2<Real> & p2,
						 const Vector2<Real> & p3,
						 Real & MaxSV, Real & MinSV, Real & L2Norm, Real & LInfNorm )
{
	Real s1 = p1.X();
	Real t1 = p1.Y();
	Real s2 = p2.X();
	Real t2 = p2.Y();
	Real s3 = p3.X();
	Real t3 = p3.Y();

	Real A = (Real)0.5 * ( (s2 - s1) * (t3 - t1) - (s3 - s1) * (t2 - t1));
	if ( A > 0 ) {

		Wml::Vector3<Real> Ss = 
			(q1 * (t2-t3) + q2 * (t3-t1) + q3 * (t1-t2)) / (2*A);
		Wml::Vector3<Real> St = 
			(q1 * (s3-s2) + q2 * (s1-s3) + q3 * (s2-s1)) / (2*A);

		Real a = Ss.Dot(Ss);
		Real b = Ss.Dot(St);
		Real c = St.Dot(St);

		Real discrim = (Real)sqrt( (a-c)*(a-c) + 4*b*b );

		MaxSV = (Real)sqrt( (Real)0.5 * ( (a+c) + discrim ) );
		MinSV = (Real)sqrt( (Real)0.5 * ( (a+c) - discrim ) );

		L2Norm = (Real)sqrt( (Real)0.5 * (a+c)  );
		LInfNorm = MaxSV;
	} else {
		MaxSV = MinSV = L2Norm = LInfNorm = std::numeric_limits<Real>::max();
	}

}
예제 #4
0
Real rms::VectorCot( const Wml::Vector3<Real> & v1, const Wml::Vector3<Real> & v2 )
{
	Real fDot = v1.Dot(v2);
	return fDot / (Real)sqrt( v1.Dot(v1) * v2.Dot(v2) - fDot*fDot );
}
예제 #5
0
Real rms::VectorAngle( const Wml::Vector3<Real> & v1, const Wml::Vector3<Real> & v2 )
{
	Real fDot = Clamp(v1.Dot(v2), (Real)-1.0, (Real)1.0);
	return (Real)acos(fDot);
}