using System; using System.Collections; using System.Collections.Generic; using UnityEngine; /// /// 贝塞尔曲线 /// [Serializable] public class BezierCurve { /// /// 段数 /// [Range(1, 100)] public int segments = 10; /// /// 是否循环 /// public bool loop; /// /// 点集合 /// public List points = new List(2) { new BezierCurvePoint() { position = Vector3.back * 5f, tangent = Vector3.back * 5f + Vector3.left * 3f }, new BezierCurvePoint() { position = Vector3.forward * 5f, tangent = Vector3.forward * 5f + Vector3.right * 3f } }; /// /// 根据归一化位置值获取对应的贝塞尔曲线上的点 /// /// 归一化位置值 [0,1] /// public Vector3 EvaluatePosition(float t) { Vector3 retVal = Vector3.zero; if (points.Count > 0) { float max = points.Count - 1 < 1 ? 0 : (loop ? points.Count : points.Count - 1); float standardized = (loop && max > 0) ? ((t %= max) + (t < 0 ? max : 0)) : Mathf.Clamp(t, 0, max); int rounded = Mathf.RoundToInt(standardized); int i1, i2; if (Mathf.Abs(standardized - rounded) < Mathf.Epsilon) i1 = i2 = (rounded == points.Count) ? 0 : rounded; else { i1 = Mathf.FloorToInt(standardized); if (i1 >= points.Count) { standardized -= max; i1 = 0; } i2 = Mathf.CeilToInt(standardized); i2 = i2 >= points.Count ? 0 : i2; } retVal = i1 == i2 ? points[i1].position : BezierCurveUtility.Bezier3(points[i1].position, points[i1].position + points[i1].tangent, points[i2].position - points[i2].tangent, points[i2].position, standardized - i1); } return retVal; } } [Serializable] public struct BezierCurvePoint { /// /// 坐标点 /// public Vector3 position; /// /// 控制点 与坐标点形成切线 /// public Vector3 tangent; } public class BezierCurveUtility { /// /// 三阶贝塞尔曲线 /// /// 起点 /// 控制点1 /// 控制点2 /// 终点 /// [0,1] /// public static Vector3 Bezier3(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) { Vector3 p0p1 = (1 - t) * p0 + t * p1; Vector3 p1p2 = (1 - t) * p1 + t * p2; Vector3 p2p3 = (1 - t) * p2 + t * p3; Vector3 p0p1p2 = (1 - t) * p0p1 + t * p1p2; Vector3 p1p2p3 = (1 - t) * p1p2 + t * p2p3; return (1 - t) * p0p1p2 + t * p1p2p3; } }