using System.Collections.Generic; using Fort23.Core; using UnityEngine; namespace Core.Utility { [System.Serializable] /// /// 贝塞尔曲线 /// public class BesselPath : CObject { public List controlPoints = new List(); public Vector3 CalculatePoint(float t) { if (controlPoints.Count < 2) { Debug.LogError("需要至少2个控制点来计算贝塞尔曲线"); return Vector3.zero; } t = Mathf.Clamp01(t); // return controlPoints[0] * ((1 - t) * (1 - t) * (1 - t)) + // controlPoints[1] * (3 * t * (1 - t) * (1 - t)) + // controlPoints[2] * (3 * t * t * (1 - t)) + // controlPoints[3] * (t * t * t); int n = controlPoints.Count - 1; // 阶数 Vector3 point = Vector3.zero; for (int i = 0; i <= n; i++) { // 计算伯恩斯坦多项式 float bernstein = Bernstein(n, i, t); point += bernstein * controlPoints[i]; } return point; } // 计算伯恩斯坦多项式 private float Bernstein(int n, int i, float t) { return BinomialCoefficient(n, i) * Mathf.Pow(1 - t, n - i) * Mathf.Pow(t, i); } public float GetLengthAtT(float t, int segments = 50) { if (controlPoints.Count < 2) return 0f; t = Mathf.Clamp01(t); float length = 0f; Vector3 previousPoint = CalculatePoint(0); float step = 1.0f / segments; for (int i = 1; i <= segments; i++) { float currentT = i * step; if (currentT < t) { continue; } Vector3 currentPoint = CalculatePoint(currentT); length += Vector3.Distance(previousPoint, currentPoint); previousPoint = currentPoint; } return length; } // 计算二项式系数 C(n,i) private float BinomialCoefficient(int n, int i) { return Factorial(n) / (Factorial(i) * Factorial(n - i)); } // 计算阶乘 private float Factorial(int n) { if (n <= 1) return 1; float result = 1; for (int i = 2; i <= n; i++) { result *= i; } return result; } // 获取曲线的切线(数值近似) public Vector3 GetTangent(float t) { const float delta = 0.001f; t = Mathf.Clamp01(t); // 使用数值微分近似切线 Vector3 p1 = CalculatePoint(t - delta); Vector3 p2 = CalculatePoint(t + delta); return (p2 - p1).normalized; } public override void ActiveObj() { } public override void DormancyObj() { controlPoints.Clear(); } } }