38 #ifndef __MO_MATH_CURVE_H__
39 #define __MO_MATH_CURVE_H__
96 virtual Real GetLength (Real fT0, Real fT1)
const = 0;
101 Real fSpeed = kVelocity.
Length();
108 return GetLength(m_fTMin,m_fTMax);
132 rkPosition = GetPosition(fTime);
133 rkTangent = GetFirstDerivative(fTime);
135 rkNormal = rkTangent.
Perp();
147 Real fNumer = kDer1.
DotPerp(kDer2);
149 return fNumer/fDenom;
164 Real fDelta = (m_fTMax - m_fTMin)/(iNumPoints-1);
166 for (
int i = 0; i < iNumPoints; i++)
168 Real fTime = m_fTMin + fDelta*i;
169 rakPoint[i] = GetPosition(fTime);
176 virtual Real GetTime (Real fLength,
int iIterations = 32,
177 Real fTolerance = (Real)1e-06)
const = 0;
185 Real fDelta = GetTotalLength()/(iNumPoints-1);
187 for (
int i = 0; i < iNumPoints; i++)
189 Real fLength = fDelta*i;
190 Real fTime = GetTime(fLength);
191 rakPoint[i] = GetPosition(fTime);
211 SubdivideByVariation(m_fTMin,kPMin,m_fTMax,kPMax,fMinVariation,
212 iMaxLevel,riNumPoints,pkList->
m_kNext);
216 for (
int i = 0; i < riNumPoints; i++)
230 virtual Real GetVariation (Real fT0, Real fT1,
255 int iLevel,
int& riNumPoints,
PointList*& rpkList)
const
257 if (iLevel > 0 && GetVariation(fT0,fT1,&rkP0,&rkP1) > fMinVariation)
261 Real fTMid = ((Real)0.5)*(fT0+fT1);
264 SubdivideByVariation(fT0,rkP0,fTMid,kPMid,fMinVariation,iLevel,
265 riNumPoints,rpkList);
267 SubdivideByVariation(fTMid,kPMid,fT1,rkP1,fMinVariation,iLevel,
268 riNumPoints,rpkList);
287 template <
class Real>
306 virtual Real
GetTime (Real fLength,
int iIterations = 32,
307 Real fTolerance = (Real)1e-06)
const
309 if (fLength <= (Real)0.0)
314 if (fLength >= GetTotalLength())
320 Real fRatio = fLength/GetTotalLength();
321 Real fOmRatio = ((Real)1.0) - fRatio;
322 Real fTime = fOmRatio*m_fTMin + fRatio*m_fTMax;
324 for (
int i = 0; i < iIterations; i++)
326 Real fDifference = GetLength(m_fTMin,fTime) - fLength;
332 fTime -= fDifference/this->GetSpeed(fTime);
362 template <
class Real>
370 m_iSegments = iSegments;
378 delete[] m_afAccumLength;
402 GetKeyInfo(fT0,iKey0,fDt0);
403 GetKeyInfo(fT1,iKey1,fDt1);
410 for (
int i = iKey0+1; i < iKey1; i++)
412 fLength += m_afLength[i];
416 fLength += GetLengthKey(iKey0,fDt0,m_afTime[iKey0+1]-m_afTime[iKey0]);
419 fLength += GetLengthKey(iKey1,(Real)0.0,fDt1);
423 fLength = GetLengthKey(iKey0,fDt0,fDt1);
429 virtual Real
GetTime (Real fLength,
int iIterations = 32,
430 Real fTolerance = (Real)1e-06)
const {
436 if (fLength <= (Real)0.0)
441 if (fLength >= m_afAccumLength[m_iSegments-1])
447 for (iKey = 0; iKey < m_iSegments; iKey++)
449 if (fLength < m_afAccumLength[iKey])
454 if (iKey >= m_iSegments)
456 return m_afTime[m_iSegments];
464 fL1 = m_afAccumLength[0];
468 fL0 = fLength - m_afAccumLength[iKey-1];
469 fL1 = m_afAccumLength[iKey] - m_afAccumLength[iKey-1];
473 Real fDt1 = m_afTime[iKey+1] - m_afTime[iKey];
474 Real fDt0 = fDt1*fL0/fL1;
475 for (
int i = 0; i < iIterations; i++)
477 Real fDifference = GetLengthKey(iKey,(Real)0.0,fDt0) - fL0;
480 return m_afTime[iKey] + fDt0;
483 fDt0 -= fDifference/GetSpeedKey(iKey,fDt0);
491 return m_afTime[iKey] + fDt0;
505 kP0 = this->GetPosition(fT0);
510 kP1 = this->GetPosition(fT1);
513 Real fInvDT = ((Real)1.0)/(fT1 - fT0);
518 GetKeyInfo(fT0,iKey0,fDt0);
519 GetKeyInfo(fT1,iKey1,fDt1);
525 fVariation = (Real)0.0;
526 for (
int i = iKey0+1; i < iKey1; i++)
528 kA = *pkP0 + (m_afTime[i] - fT0)*kB;
529 fVariation += GetVariationKey(i,(Real)0.0,
530 m_afTime[i+1]-m_afTime[i],kA,kB);
534 kA = *pkP0 + (m_afTime[iKey0] - fT0)*kB;
535 fVariation += GetVariationKey(iKey0,fDt0,
536 m_afTime[iKey0+1]-m_afTime[iKey0],kA,kB);
539 kA = *pkP0 + (m_afTime[iKey1] - fT0)*kB;
540 fVariation += GetVariationKey(iKey1,(Real)0.0,fDt1,kA,kB);
544 kA = *pkP0 + (m_afTime[iKey0] - fT0)*kB;
545 fVariation = GetVariationKey(iKey0,fDt0,fDt1,kA,kB);
567 if (fTime <= m_afTime[0])
572 else if (fTime >= m_afTime[m_iSegments])
574 riKey = m_iSegments-1;
575 rfDt = m_afTime[m_iSegments] - m_afTime[m_iSegments-1];
579 for (
int i = 0; i < m_iSegments; i++)
581 if (fTime < m_afTime[i+1])
584 rfDt = fTime - m_afTime[i];
592 m_afLength =
new Real[m_iSegments];
593 m_afAccumLength =
new Real[m_iSegments];
597 for (iKey = 0; iKey < m_iSegments; iKey++)
599 m_afLength[iKey] = GetLengthKey(iKey,(Real)0.0,
600 m_afTime[iKey+1]-m_afTime[iKey]);
604 m_afAccumLength[0] = m_afLength[0];
605 for (iKey = 1; iKey < m_iSegments; iKey++)
607 m_afAccumLength[iKey] = m_afAccumLength[iKey-1] + m_afLength[iKey];
610 virtual Real GetSpeedKey (
int iKey, Real fTime)
const = 0;
611 virtual Real GetLengthKey (
int iKey, Real fT0, Real fT1)
const = 0;
612 virtual Real GetVariationKey (
int iKey, Real fT0, Real fT1,
617 int iKey = *(
int*)((
char*)pvData +
sizeof(pvThis));
630 template <
class Real>
666 virtual Real GetTime (Real fLength,
int iIterations = 32,
667 Real fTolerance = (Real)1e-06)
const = 0;
668 virtual Real GetVariation (Real fT0, Real fT1,
673 virtual Real GetLength (Real fT0, Real fT1)
const = 0;
677 Real fSpeed = kVelocity.
Length();
682 return GetLength(m_fTMin,m_fTMax);
693 Real fVDotV = kVelocity.
Dot(kVelocity);
694 Real fVDotA = kVelocity.
Dot(kAcceleration);
704 Real fVDotV = kVelocity.
Dot(kVelocity);
705 Real fVDotA = kVelocity.
Dot(kAcceleration);
708 kVelocity.Normalize();
718 rkPosition = GetPosition(fTime);
721 Real fVDotV = kVelocity.
Dot(kVelocity);
722 Real fVDotA = kVelocity.
Dot(kAcceleration);
723 rkNormal = fVDotV*kAcceleration - fVDotA*kVelocity;
725 rkTangent = kVelocity;
727 rkBinormal = rkTangent.
Cross(rkNormal);
740 Real fNumer = kCross.
Length();
742 return fNumer/fDenom;
762 Real fNumer = kCross.
Dot(kJerk);
763 return fNumer/fDenom;
779 Real fDelta = (m_fTMax - m_fTMin)/(iNumPoints-1);
781 for (
int i = 0; i < iNumPoints; i++)
783 Real fTime = m_fTMin + fDelta*i;
784 rakPoint[i] = GetPosition(fTime);
795 Real fDelta = GetTotalLength()/(iNumPoints-1);
797 for (
int i = 0; i < iNumPoints; i++)
799 Real fLength = fDelta*i;
800 Real fTime = GetTime(fLength);
801 rakPoint[i] = GetPosition(fTime);
826 int& riNumPoints,
PointList*& rpkList)
const
828 if (iLevel > 0 && GetVariation(fT0,fT1,&rkP0,&rkP1) > fMinVariation)
832 Real fTMid = ((Real)0.5)*(fT0+fT1);
835 SubdivideByVariation(fT0,rkP0,fTMid,kPMid,fMinVariation,iLevel,
836 riNumPoints,rpkList);
838 SubdivideByVariation(fTMid,kPMid,fT1,rkP1,fMinVariation,iLevel,
839 riNumPoints,rpkList);
858 template <
class Real>
874 Real fTolerance)
const
876 if (fLength <= (Real)0.0)
881 if (fLength >= GetTotalLength())
887 Real fRatio = fLength/GetTotalLength();
888 Real fOmRatio = (Real)1.0 - fRatio;
889 Real fTime = fOmRatio*m_fTMin + fRatio*m_fTMax;
891 for (
int i = 0; i < iIterations; i++)
893 Real fDifference = GetLength(m_fTMin,fTime) - fLength;
899 fTime -= fDifference/this->GetSpeed(fTime);
929 template <
class Real>
937 moCurve3<Real>(afTime[0],afTime[iSegments])
939 m_iSegments = iSegments;
947 delete[] m_afAccumLength;
967 GetKeyInfo(fT0,iKey0,fDt0);
968 GetKeyInfo(fT1,iKey1,fDt1);
975 for (
int i = iKey0+1; i < iKey1; i++)
976 fLength += m_afLength[i];
979 fLength += GetLengthKey(iKey0,fDt0,m_afTime[iKey0+1]-m_afTime[iKey0]);
982 fLength += GetLengthKey(iKey1,(Real)0.0,fDt1);
986 fLength = GetLengthKey(iKey0,fDt0,fDt1);
992 virtual Real
GetTime (Real fLength,
int iIterations = 32,
993 Real fTolerance = (Real)1e-06)
const {
999 if (fLength <= (Real)0.0)
1004 if (fLength >= m_afAccumLength[m_iSegments-1])
1010 for (iKey = 0; iKey < m_iSegments; iKey++)
1012 if (fLength < m_afAccumLength[iKey])
1017 if (iKey >= m_iSegments)
1019 return m_afTime[m_iSegments];
1027 fL1 = m_afAccumLength[0];
1031 fL0 = fLength - m_afAccumLength[iKey-1];
1032 fL1 = m_afAccumLength[iKey] - m_afAccumLength[iKey-1];
1036 Real fDt1 = m_afTime[iKey+1] - m_afTime[iKey];
1037 Real fDt0 = fDt1*fL0/fL1;
1038 for (
int i = 0; i < iIterations; i++)
1040 Real fDifference = GetLengthKey(iKey,(Real)0.0,fDt0) - fL0;
1043 return m_afTime[iKey] + fDt0;
1046 fDt0 -= fDifference/GetSpeedKey(iKey,fDt0);
1054 return m_afTime[iKey] + fDt0;
1069 kP0 = this->GetPosition(fT0);
1074 kP1 = this->GetPosition(fT1);
1077 Real fInvDT = ((Real)1.0)/(fT1 - fT0);
1082 GetKeyInfo(fT0,iKey0,fDt0);
1083 GetKeyInfo(fT1,iKey1,fDt1);
1089 fVariation = (Real)0.0;
1090 for (
int i = iKey0+1; i < iKey1; i++)
1092 kA = *pkP0 + (m_afTime[i] - fT0)*kB;
1093 fVariation += GetVariationKey(i,(Real)0.0,
1094 m_afTime[i+1]-m_afTime[i],kA,kB);
1098 kA = *pkP0 + (m_afTime[iKey0] - fT0)*kB;
1099 fVariation += GetVariationKey(iKey0,fDt0,
1100 m_afTime[iKey0+1]-m_afTime[iKey0],kA,kB);
1103 kA = *pkP0 + (m_afTime[iKey1] - fT0)*kB;
1104 fVariation += GetVariationKey(iKey1,0.0f,fDt1,kA,kB);
1108 kA = *pkP0 + (m_afTime[iKey0] - fT0)*kB;
1109 fVariation = GetVariationKey(iKey0,fDt0,fDt1,kA,kB);
1112 return fVariation; }
1130 if (fTime <= m_afTime[0])
1135 else if (fTime >= m_afTime[m_iSegments])
1137 riKey = m_iSegments-1;
1138 rfDt = m_afTime[m_iSegments] - m_afTime[m_iSegments-1];
1142 for (
int i = 0; i < m_iSegments; i++)
1144 if (fTime < m_afTime[i+1])
1147 rfDt = fTime - m_afTime[i];
1155 m_afLength =
new Real[m_iSegments];
1156 m_afAccumLength =
new Real[m_iSegments];
1160 for (iKey = 0; iKey < m_iSegments; iKey++)
1162 m_afLength[iKey] = GetLengthKey(iKey,(Real)0.0,
1163 m_afTime[iKey+1]-m_afTime[iKey]);
1167 m_afAccumLength[0] = m_afLength[0];
1168 for (iKey = 1; iKey < m_iSegments; iKey++)
1170 m_afAccumLength[iKey] = m_afAccumLength[iKey-1] + m_afLength[iKey];
1173 virtual Real GetSpeedKey (
int iKey, Real fTime)
const = 0;
1174 virtual Real GetLengthKey (
int iKey, Real fT0, Real fT1)
const = 0;
1175 virtual Real GetVariationKey (
int iKey, Real fT0, Real fT1,
1180 int iKey = *(
int*)((
char*)pvData +
sizeof(pvThis));
moVector3< Real > GetTangent(Real fTime) const
Real GetSpeed(Real fTime) const
void GetKeyInfo(Real fTime, int &riKey, Real &rfDt) const
moSingleCurve3< MOfloat > moSingleCurve3f
Real GetTotalLength() const
moMultipleCurve2< MOfloat > moMultipleCurve2f
virtual Real GetVariation(Real fT0, Real fT1, const moVector2< Real > *pkP0=0, const moVector2< Real > *pkP1=0) const
Real SquaredLength() const
Real GetTime(Real fLength, int iIterations, Real fTolerance) const
void SetTimeInterval(Real fTMin, Real fTMax)
static Real GetSpeedWithData(Real fTime, void *pvData)
moCurve3< MOfloat > moCurve3f
void SubdivideByTime(int iNumPoints, moVector3< Real > *&rakPoint) const
moMultipleCurve2(int iSegments, Real *afTime)
static Real RombergIntegral(int iOrder, Real fA, Real fB, Function oF, void *pvUserData=0)
virtual Real GetLength(Real fT0, Real fT1) const
moSingleCurve2< MOdouble > moSingleCurve2d
void InitializeLength() const
moMultipleCurve3< MOfloat > moMultipleCurve3f
Real GetTotalLength() const
const Real * GetTimes() const
Clase base abstracta de donde deben derivar los objetos [virtual pura].
void InitializeLength() const
virtual Real GetSpeedKey(int iKey, Real fTime) const =0
virtual ~moMultipleCurve3()
virtual ~moMultipleCurve2()
moVector2< Real > GetTangent(Real fTime) const
moSingleCurve3(Real fTMin, Real fTMax)
moCurve2< MOdouble > moCurve2d
virtual Real GetLength(Real fT0, Real fT1) const
virtual Real GetVariation(Real fT0, Real fT1, const moVector3< Real > *pkP0=0, const moVector3< Real > *pkP1=0) const
void SetTimeInterval(Real fTMin, Real fTMax)
void GetFrame(Real fTime, moVector2< Real > &rkPosition, moVector2< Real > &rkTangent, moVector2< Real > &rkNormal) const
void SubdivideByLength(int iNumPoints, moVector2< Real > *&rakPoint) const
PointList(const moVector2< Real > &rkPoint, PointList *pkNext)
Real GetSpeed(Real fTime) const
void SubdivideByVariation(Real fT0, const moVector2< Real > &rkP0, Real fT1, const moVector2< Real > &rkP1, Real fMinVariation, int iLevel, int &riNumPoints, PointList *&rpkList) const
moVector2< Real > GetNormal(Real fTime) const
virtual Real GetTime(Real fLength, int iIterations=32, Real fTolerance=(Real) 1e-06) const
Real GetTorsion(Real fTime) const
void GetKeyInfo(Real fTime, int &riKey, Real &rfDt) const
moMultipleCurve3(int iSegments, Real *afTime)
void SubdivideByVariation(Real fMinVariation, int iMaxLevel, int &riNumPoints, moVector2< Real > *&rakPoint) const
virtual Real GetSpeedKey(int iKey, Real fTime) const =0
Real Dot(const moVector3 &rkV) const
void SubdivideByTime(int iNumPoints, moVector2< Real > *&rakPoint) const
moCurve2< MOfloat > moCurve2f
void SubdivideByLength(int iNumPoints, moVector3< Real > *&rakPoint) const
static Real GetSpeedWithData(Real fTime, void *pvData)
moMultipleCurve3< MOdouble > moMultipleCurve3d
Real GetCurvature(Real fTime) const
moSingleCurve2< MOfloat > moSingleCurve2f
moVector3< Real > GetBinormal(Real fTime) const
void SubdivideByVariation(Real fT0, const moVector3< Real > &rkP0, Real fT1, const moVector3< Real > &rkP1, Real fMinVariation, int iLevel, int &riNumPoints, PointList *&rpkList) const
virtual Real GetLength(Real fT0, Real fT1) const
virtual Real GetLength(Real fT0, Real fT1) const
virtual Real GetTime(Real fLength, int iIterations=32, Real fTolerance=(Real) 1e-06) const
moCurve3< MOdouble > moCurve3d
PointList(const moVector3< Real > &rkPoint, PointList *pkNext)
moVector3 Cross(const moVector3 &rkV) const
Real SquaredLength() const
static Real GetSpeedWithData(Real fTime, void *pvData)
const Real * GetTimes() const
moCurve2(Real fTMin, Real fTMax)
Real DotPerp(const moVector2 &rkV) const
returns DotPerp((x,y),(V.x,V.y)) = x*V.y - y*V.x
moVector2< Real > m_kPoint
static Real Pow(Real fBase, Real fExponent)
moVector2 Perp() const
returns (y,-x)
moSingleCurve3< MOdouble > moSingleCurve3d
moVector3< Real > GetNormal(Real fTime) const
void GetFrame(Real fTime, moVector3< Real > &rkPosition, moVector3< Real > &rkTangent, moVector3< Real > &rkNormal, moVector3< Real > &rkBinormal) const
moVector3< Real > m_kPoint
moMultipleCurve2< MOdouble > moMultipleCurve2d
Real GetCurvature(Real fTime) const
moSingleCurve2(Real fTMin, Real fTMax)
static Real GetSpeedWithData(Real fTime, void *pvData)
virtual Real GetTime(Real fLength, int iIterations=32, Real fTolerance=(Real) 1e-06) const
moCurve3(Real fTMin, Real fTMax)