BesselPath.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System.Collections.Generic;
  2. using Fort23.Core;
  3. using UnityEngine;
  4. namespace Core.Utility
  5. {
  6. /// <summary>
  7. /// 贝塞尔曲线
  8. /// </summary>
  9. public class BesselPath :CObject
  10. {
  11. public BetterList<Vector3> controlPoints = new BetterList<Vector3>();
  12. public Vector3 CalculatePoint(float t)
  13. {
  14. if (controlPoints.Count < 2)
  15. {
  16. Debug.LogError("需要至少2个控制点来计算贝塞尔曲线");
  17. return Vector3.zero;
  18. }
  19. t = Mathf.Clamp01(t);
  20. int n = controlPoints.Count - 1; // 阶数
  21. Vector3 point = Vector3.zero;
  22. for (int i = 0; i <= n; i++)
  23. {
  24. // 计算伯恩斯坦多项式
  25. float bernstein = Bernstein(n, i, t);
  26. point += bernstein * controlPoints[i];
  27. }
  28. return point;
  29. }
  30. // 计算伯恩斯坦多项式
  31. private float Bernstein(int n, int i, float t)
  32. {
  33. return BinomialCoefficient(n, i) * Mathf.Pow(1 - t, n - i) * Mathf.Pow(t, i);
  34. }
  35. // 计算二项式系数 C(n,i)
  36. private float BinomialCoefficient(int n, int i)
  37. {
  38. return Factorial(n) / (Factorial(i) * Factorial(n - i));
  39. }
  40. // 计算阶乘
  41. private float Factorial(int n)
  42. {
  43. if (n <= 1) return 1;
  44. float result = 1;
  45. for (int i = 2; i <= n; i++)
  46. {
  47. result *= i;
  48. }
  49. return result;
  50. }
  51. // 获取曲线的切线(数值近似)
  52. public Vector3 GetTangent(float t)
  53. {
  54. const float delta = 0.001f;
  55. t = Mathf.Clamp01(t);
  56. // 使用数值微分近似切线
  57. Vector3 p1 = CalculatePoint(t - delta);
  58. Vector3 p2 = CalculatePoint(t + delta);
  59. return (p2 - p1).normalized;
  60. }
  61. public override void ActiveObj()
  62. {
  63. }
  64. public override void DormancyObj()
  65. {
  66. controlPoints.Clear();
  67. }
  68. }
  69. }