112 lines
2.8 KiB
C#
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);
|
|
}
|
|
}
|