QuinticBezierCurve.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using UnityEngine;
  2. namespace Core.Utility
  3. {
  4. public class QuinticBezierCurve: MonoBehaviour
  5. {
  6. // 5个控制点
  7. public Vector3 p0; // 起点
  8. public Vector3 p1; // 控制点1
  9. public Vector3 p2; // 控制点2
  10. public Vector3 p3; // 控制点3
  11. public Vector3 p4; // 终点
  12. // 计算四阶贝塞尔曲线上的点
  13. // t: 参数,范围 [0, 1]
  14. public Vector3 CalculatePoint(float t)
  15. {
  16. // 确保 t 在 0-1 范围内
  17. t = Mathf.Clamp01(t);
  18. // 四阶贝塞尔曲线公式
  19. // B(t) = (1-t)^4 * P0 + 4(1-t)^3 * t * P1 + 6(1-t)^2 * t^2 * P2 + 4(1-t) * t^3 * P3 + t^4 * P4
  20. float u = 1 - t;
  21. float t2 = t * t;
  22. float t3 = t2 * t;
  23. float t4 = t3 * t;
  24. float u2 = u * u;
  25. float u3 = u2 * u;
  26. float u4 = u3 * u;
  27. Vector3 point = (u4 * p0) +
  28. (4 * u3 * t * p1) +
  29. (6 * u2 * t2 * p2) +
  30. (4 * u * t3 * p3) +
  31. (t4 * p4);
  32. return point;
  33. }
  34. // 示例:在场景中绘制曲线
  35. void OnDrawGizmos()
  36. {
  37. Gizmos.color = Color.yellow;
  38. // 绘制控制点
  39. Gizmos.DrawSphere(p0, 0.1f);
  40. Gizmos.DrawSphere(p1, 0.1f);
  41. Gizmos.DrawSphere(p2, 0.1f);
  42. Gizmos.DrawSphere(p3, 0.1f);
  43. Gizmos.DrawSphere(p4, 0.1f);
  44. // 绘制曲线
  45. Vector3 previousPoint = p0;
  46. int segments = 50;
  47. for (int i = 1; i <= segments; i++)
  48. {
  49. float t = i / (float)segments;
  50. Vector3 currentPoint = CalculatePoint(t);
  51. Gizmos.DrawLine(previousPoint, currentPoint);
  52. previousPoint = currentPoint;
  53. }
  54. }
  55. // 获取曲线的切线(导数)
  56. public Vector3 GetTangent(float t)
  57. {
  58. t = Mathf.Clamp01(t);
  59. float u = 1 - t;
  60. // 四阶贝塞尔曲线的导数
  61. Vector3 tangent = 4 * (u * u * u * (p1 - p0) +
  62. 3 * u * u * t * (p2 - p1) +
  63. 3 * u * t * t * (p3 - p2) +
  64. t * t * t * (p4 - p3));
  65. return tangent.normalized;
  66. }
  67. }
  68. }