using System.Collections.Generic; using UnityEngine; /*网址 https://blog.csdn.net/linxinfa/article/details/116808549 */ /// /// 贝塞尔曲线工具 /// public class BezierCurve : MonoBehaviour { /// /// 控制点(包括起始点和终止点) /// [SerializeField] private Transform[] points; /// /// 精确度 /// [SerializeField] private int accuracy = 20; private void Update() { // 绘制贝塞尔曲线 Vector3 prev_pos = points[0].position; for (int i = 0; i <= accuracy; ++i) { Vector3 to = CalculateBezierPoint(i / (float)accuracy, points); Debug.DrawLine(prev_pos, to, Color.green); prev_pos = to; } } private void OnDrawGizmos() { Gizmos.color = Color.white; // 绘制控制点(包括起始点和终止点) for (int i = 0; i < points.Length; ++i) { if (i < points.Length - 1) { if (4 == points.Length && i == 1) { continue; } Vector3 current = points[i].position; Vector3 next = points[i + 1].position; Gizmos.DrawLine(current, next); } } } /// /// 返回曲线路径 /// /// public List GeneratePaths() { List paths = new List(); for (int i = 0; i <= accuracy; ++i) { Vector3 to = CalculateBezierPoint(i / (float)accuracy, points); paths.Add(to); } return paths; } /// /// 计算贝塞尔点 /// private Vector3 CalculateBezierPoint(float t, Transform[] controlPoints) { Vector3[] points = new Vector3[controlPoints.Length]; for (int i = 0; i < controlPoints.Length; i++) { points[i] = controlPoints[i].position; } return CalculateBezierPoint(t, points); } /// /// 计算贝塞尔点 /// private Vector3 CalculateBezierPoint(float t, Vector3[] points) { int n = points.Length - 1; Vector3 result = Vector3.zero; for (int i = 0; i <= n; i++) { result += BinomialCoefficient(n, i) * Mathf.Pow(1 - t, n - i) * Mathf.Pow(t, i) * points[i]; } return result; } /// /// 二项式系数 /// private int BinomialCoefficient(int n, int k) { if (k == 0 || k == n) { return 1; } return BinomialCoefficient(n - 1, k - 1) + BinomialCoefficient(n - 1, k); } }