Raw File
Curve.cpp
// Geometric Tools, LLC
// Copyright (c) 1998-2012
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 5.0.1 (2010/10/01)

#include "Curve.h"

#ifndef QT_DEBUG
	// Standard resolution
	int TIME_ITERATIONS			= 16;
	double CURVE_TOLERANCE		= 1e-06;
	int RombergIntegralOrder	= 7;
#else
	// Lower resolution
	int TIME_ITERATIONS			= 8;
	double CURVE_TOLERANCE		= 1e-05;
	int RombergIntegralOrder	= 3;
#endif

namespace NURBS
{
//----------------------------------------------------------------------------
template <typename Real>
Curve<Real>::Curve (Real tmin, Real tmax)
{
    mTMin = tmin;
    mTMax = tmax;
}

//----------------------------------------------------------------------------
template <typename Real>
Real Curve<Real>::GetMinTime ()
{
    return mTMin;
}
//----------------------------------------------------------------------------
template <typename Real>
Real Curve<Real>::GetMaxTime ()
{
    return mTMax;
}
//----------------------------------------------------------------------------
template <typename Real>
void Curve<Real>::SetTimeInterval (Real tmin, Real tmax)
{
    assertion(tmin < tmax, "Invalid time interval\n");
    mTMin = tmin;
    mTMax = tmax;
}
//----------------------------------------------------------------------------
template <typename Real>
Real Curve<Real>::GetSpeed (Real t)
{
    Vector3 velocity = GetFirstDerivative(t);
    Real speed = velocity.norm();
    return speed;
}
//----------------------------------------------------------------------------
template <typename Real>
Real Curve<Real>::GetTotalLength ()
{
    return GetLength(mTMin, mTMax);
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 Curve<Real>::GetTangent (Real t)
{
    Vector3 velocity = GetFirstDerivative(t);
    velocity.normalize();
    return velocity;
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 Curve<Real>::GetNormal (Real t)
{
    Vector3 velocity = GetFirstDerivative(t);
    Vector3 acceleration = GetSecondDerivative(t);
    Real VDotV = dot(velocity,velocity);
    Real VDotA = dot(velocity,acceleration);
    Vector3 normal = VDotV*acceleration - VDotA*velocity;
    normal.normalize();
    return normal;
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 Curve<Real>::GetBinormal (Real t)
{
    Vector3 velocity = GetFirstDerivative(t);
    Vector3 acceleration = GetSecondDerivative(t);
    Real VDotV = dot(velocity,velocity);
    Real VDotA = dot(velocity,acceleration);
    Vector3 normal = VDotV*acceleration - VDotA*velocity;
    normal.normalize();
    velocity.normalize();
    Vector3 binormal = cross(velocity,normal);
    return binormal;
}
//----------------------------------------------------------------------------
template <typename Real>
void Curve<Real>::GetFrame (Real t, Vector3& position,
    Vector3& tangent, Vector3& normal, Vector3& binormal)

{
    position = GetPosition(t);
    Vector3 velocity = GetFirstDerivative(t);
    Vector3 acceleration = GetSecondDerivative(t);
    Real VDotV = dot(velocity,velocity);
    Real VDotA = dot(velocity,acceleration);
    normal = VDotV*acceleration - VDotA*velocity;
    normal.normalize();
    tangent = velocity;
    tangent.normalize();
    binormal = cross(tangent,normal);
}
//----------------------------------------------------------------------------
template <typename Real>
Real Curve<Real>::GetCurvature (Real t)
{
    Vector3 velocity = GetFirstDerivative(t);
    Real speedSqr = velocity.squaredNorm();

    if (speedSqr >= REAL_ZERO_TOLERANCE)
    {
        Vector3 acceleration = GetSecondDerivative(t);
        Vector3 _cross = cross(velocity,acceleration);
        Real numer = _cross.norm();
        Real denom = pow(speedSqr, (Real)1.5);
        return numer/denom;
    }
    else
    {
        // Curvature is indeterminate, just return 0.
        return (Real)0;
    }
}
//----------------------------------------------------------------------------
template <typename Real>
Real Curve<Real>::GetTorsion (Real t)
{
    Vector3 velocity = GetFirstDerivative(t);
    Vector3 acceleration = GetSecondDerivative(t);
    Vector3 _cross = cross(velocity,acceleration);
    Real denom = _cross.squaredNorm();

    if (denom >= REAL_ZERO_TOLERANCE)
    {
        Vector3 jerk = GetThirdDerivative(t);
        Real numer = dot(_cross,jerk);
        return numer/denom;
    }
    else
    {
        // Torsion is indeterminate, just return 0.
        return (Real)0;
    }
}
//----------------------------------------------------------------------------
template <typename Real>
void Curve<Real>::SubdivideByTime (int numPoints, Array1D_Vector3& points)
{
    assertion(numPoints >= 2, "Subdivision requires at least two points\n");
    points = new1<Vector3>(numPoints);

    Real delta = (mTMax - mTMin)/(numPoints - 1);

    for (int i = 0; i < numPoints; ++i)
    {
        Real t = mTMin + delta*i;
        points[i] = GetPosition(t);
    }
}
//----------------------------------------------------------------------------
template <typename Real>
void Curve<Real>::SubdivideByLength (int numPoints, Array1D_Vector3& points)
{
    assertion(numPoints >= 2, "Subdivision requires at least two points\n");
    points = new1<Vector3>(numPoints);

    Real delta = GetTotalLength()/(numPoints - 1);

    for (int i = 0; i < numPoints; ++i)
    {
        Real length = delta*i;
        Real t = GetTime(length, TIME_ITERATIONS, CURVE_TOLERANCE);
        points[i] = GetPosition(t);
    }
}
//----------------------------------------------------------------------------

template <typename Real>
void Curve<Real>::SubdivideByLengthTime (int numPoints, std::vector<Real> & times)
{
    assert(numPoints >= 2);
    times.resize(numPoints);

	double len = GetTotalLength();

	// degenerate curve check
	if( !IsFiniteNumber(len) ){
		for (int i = 0; i < numPoints; ++i)
			times[i] = double(i) / numPoints - 1;
		return;
	}

    Real delta = len / (numPoints - 1);

    for (int i = 0; i < numPoints; ++i)
    {
        Real length = delta * i;
        times[i] = GetTime(length, TIME_ITERATIONS, CURVE_TOLERANCE);
    }
}

//----------------------------------------------------------------------------
// Explicit instantiation.
//----------------------------------------------------------------------------
//template
//class Curve<float>;

template
class Curve<double>;
//----------------------------------------------------------------------------
}
back to top