ltbeziercurve.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // This module contains functions to deal with 2D bezier curve segments.
  2. // DEdit uses the same functions.
  3. #ifndef __LTBEZIERCURVE_H__
  4. #define __LTBEZIERCURVE_H__
  5. #include "ltbasetypes.h"
  6. #include "ltvector.h"
  7. // This number is quintessentially the right number.
  8. #define DEFAULT_BEZIER_SUBDIVISIONS 20
  9. // Evaluate the Bezier curve at the specified point. t is between 0 and 1.
  10. inline void Bezier_Evaluate(LTVector &out,
  11. LTVector &pt1, LTVector &pt2,
  12. LTVector &pt3, LTVector &pt4,
  13. float t)
  14. {
  15. float oneMinusT[3];
  16. float tSquared;
  17. oneMinusT[0] = 1.0f - t;
  18. oneMinusT[1] = oneMinusT[0] * oneMinusT[0];
  19. oneMinusT[2] = oneMinusT[1] * oneMinusT[0];
  20. tSquared = t * t;
  21. out = pt1 * oneMinusT[2] +
  22. pt2 * (3.0f * t * oneMinusT[1]) +
  23. pt3 * (3.0f * tSquared * oneMinusT[0]) +
  24. pt4 * (tSquared * t);
  25. }
  26. // Returns the distance between two points on the curve.
  27. // The more subdivisions, the slower it is but the more accurate.
  28. // There must be at least 1 subdivision.
  29. // This function should use forward differencing in the future if there
  30. // are more than a few subdivisions.
  31. inline float Bezier_SubSegmentLength(
  32. LTVector &pt1, LTVector &pt2, LTVector &pt3, LTVector &pt4,
  33. float t1, float t2,
  34. uint32 nSubDivisions=DEFAULT_BEZIER_SUBDIVISIONS)
  35. {
  36. LTVector prevPt, curPt;
  37. float totalLen, tInc, tCur;
  38. nSubDivisions = LTMAX(nSubDivisions, 1);
  39. totalLen = 0.0f;
  40. Bezier_Evaluate(prevPt,
  41. pt1, pt2, pt3, pt4, t1);
  42. tInc = (t2 - t1) / nSubDivisions;
  43. tCur = t1 + tInc;
  44. while(nSubDivisions)
  45. {
  46. nSubDivisions--;
  47. Bezier_Evaluate(curPt,
  48. pt1, pt2, pt3, pt4, tCur);
  49. totalLen += (curPt - prevPt).Mag();
  50. tCur += tInc;
  51. prevPt = curPt;
  52. }
  53. return totalLen;
  54. }
  55. // Returns the (approximate) length of the curve segment. This function is pretty slow.
  56. // The more subdivisions, the slower it is but the more accurate.
  57. // There must be at least 1 subdivision.
  58. inline float Bezier_SegmentLength(
  59. LTVector &pt1, LTVector &pt2, LTVector &pt3, LTVector &pt4,
  60. uint32 nSubDivisions=DEFAULT_BEZIER_SUBDIVISIONS)
  61. {
  62. return Bezier_SubSegmentLength(pt1, pt2, pt3, pt4, 0.0f, 1.0f, nSubDivisions);
  63. }
  64. #endif // __LTBEZIERCURVE_H__