OvertakingLegend/Assets/Script/Tool/BezierCurve.cs

112 lines
2.8 KiB
C#

using System.Collections.Generic;
using UnityEngine;
/*网址
https://blog.csdn.net/linxinfa/article/details/116808549
*/
/// <summary>
/// 贝塞尔曲线工具
/// </summary>
public class BezierCurve : MonoBehaviour
{
/// <summary>
/// 控制点(包括起始点和终止点)
/// </summary>
[SerializeField]
private Transform[] points;
/// <summary>
/// 精确度
/// </summary>
[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);
}
}
}
/// <summary>
/// 返回曲线路径
/// </summary>
/// <returns></returns>
public List<Vector3> GeneratePaths()
{
List<Vector3> paths = new List<Vector3>();
for (int i = 0; i <= accuracy; ++i)
{
Vector3 to = CalculateBezierPoint(i / (float)accuracy, points);
paths.Add(to);
}
return paths;
}
/// <summary>
/// 计算贝塞尔点
/// </summary>
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);
}
/// <summary>
/// 计算贝塞尔点
/// </summary>
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;
}
/// <summary>
/// 二项式系数
/// </summary>
private int BinomialCoefficient(int n, int k)
{
if (k == 0 || k == n)
{
return 1;
}
return BinomialCoefficient(n - 1, k - 1) + BinomialCoefficient(n - 1, k);
}
}