112 lines
2.8 KiB
C#
112 lines
2.8 KiB
C#
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
/*<EFBFBD><EFBFBD>ַ
|
|||
|
|
https://blog.csdn.net/linxinfa/article/details/116808549
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߹<EFBFBD><DFB9><EFBFBD>
|
|||
|
|
/// </summary>
|
|||
|
|
public class BezierCurve : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><><EFBFBD>Ƶ㣨<C6B5><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD>㣩
|
|||
|
|
/// </summary>
|
|||
|
|
[SerializeField]
|
|||
|
|
private Transform[] points;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><>ȷ<EFBFBD><C8B7>
|
|||
|
|
/// </summary>
|
|||
|
|
[SerializeField]
|
|||
|
|
private int accuracy = 20;
|
|||
|
|
|
|||
|
|
private void Update()
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
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;
|
|||
|
|
// <20><><EFBFBD>ƿ<EFBFBD><C6BF>Ƶ㣨<C6B5><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD>㣩
|
|||
|
|
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>
|
|||
|
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
|
|||
|
|
/// </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>
|
|||
|
|
/// <20><><EFBFBD>㱴<EFBFBD><E3B1B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
/// </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>
|
|||
|
|
/// <20><><EFBFBD>㱴<EFBFBD><E3B1B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
/// </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>
|
|||
|
|
/// <20><><EFBFBD><EFBFBD>ʽϵ<CABD><CFB5>
|
|||
|
|
/// </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);
|
|||
|
|
}
|
|||
|
|
}
|