123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // This module contains functions to deal with 2D bezier curve segments.
- // DEdit uses the same functions.
- #ifndef __LTBEZIERCURVE_H__
- #define __LTBEZIERCURVE_H__
- #include "ltbasetypes.h"
- #include "ltvector.h"
- // This number is quintessentially the right number.
- #define DEFAULT_BEZIER_SUBDIVISIONS 20
- // Evaluate the Bezier curve at the specified point. t is between 0 and 1.
- inline void Bezier_Evaluate(LTVector &out,
- LTVector &pt1, LTVector &pt2,
- LTVector &pt3, LTVector &pt4,
- float t)
- {
- float oneMinusT[3];
- float tSquared;
- oneMinusT[0] = 1.0f - t;
- oneMinusT[1] = oneMinusT[0] * oneMinusT[0];
- oneMinusT[2] = oneMinusT[1] * oneMinusT[0];
- tSquared = t * t;
- out = pt1 * oneMinusT[2] +
- pt2 * (3.0f * t * oneMinusT[1]) +
- pt3 * (3.0f * tSquared * oneMinusT[0]) +
- pt4 * (tSquared * t);
- }
- // Returns the distance between two points on the curve.
- // The more subdivisions, the slower it is but the more accurate.
- // There must be at least 1 subdivision.
- // This function should use forward differencing in the future if there
- // are more than a few subdivisions.
- inline float Bezier_SubSegmentLength(
- LTVector &pt1, LTVector &pt2, LTVector &pt3, LTVector &pt4,
- float t1, float t2,
- uint32 nSubDivisions=DEFAULT_BEZIER_SUBDIVISIONS)
- {
- LTVector prevPt, curPt;
- float totalLen, tInc, tCur;
- nSubDivisions = LTMAX(nSubDivisions, 1);
- totalLen = 0.0f;
- Bezier_Evaluate(prevPt,
- pt1, pt2, pt3, pt4, t1);
- tInc = (t2 - t1) / nSubDivisions;
- tCur = t1 + tInc;
- while(nSubDivisions)
- {
- nSubDivisions--;
- Bezier_Evaluate(curPt,
- pt1, pt2, pt3, pt4, tCur);
- totalLen += (curPt - prevPt).Mag();
- tCur += tInc;
- prevPt = curPt;
- }
- return totalLen;
- }
- // Returns the (approximate) length of the curve segment. This function is pretty slow.
- // The more subdivisions, the slower it is but the more accurate.
- // There must be at least 1 subdivision.
- inline float Bezier_SegmentLength(
- LTVector &pt1, LTVector &pt2, LTVector &pt3, LTVector &pt4,
- uint32 nSubDivisions=DEFAULT_BEZIER_SUBDIVISIONS)
- {
- return Bezier_SubSegmentLength(pt1, pt2, pt3, pt4, 0.0f, 1.0f, nSubDivisions);
- }
- #endif // __LTBEZIERCURVE_H__
|