88 lines
2.5 KiB
C#
88 lines
2.5 KiB
C#
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
public static class BezierCurve
|
|||
|
|
{
|
|||
|
|
// 新增路径生成方法
|
|||
|
|
public static Vector3[] GenerateBezierPath(Vector3[] controlPoints, int segments = 20)
|
|||
|
|
{
|
|||
|
|
Vector3[] path = new Vector3[segments + 1];
|
|||
|
|
|
|||
|
|
for (int i = 0; i <= segments; i++)
|
|||
|
|
{
|
|||
|
|
float t = i / (float)segments;
|
|||
|
|
switch (controlPoints.Length)
|
|||
|
|
{
|
|||
|
|
case 2:
|
|||
|
|
path[i] = LineBezier(controlPoints[0], controlPoints[1], t);
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
path[i] = QuadraticBezier(controlPoints, t);
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
path[i] = CubicBezier(controlPoints, t);
|
|||
|
|
break;
|
|||
|
|
default: // 处理n阶情况
|
|||
|
|
path[i] = BezierInterpolation(controlPoints, t);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return path;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 一阶贝塞尔(线性插值)
|
|||
|
|
public static Vector3 LineBezier(Vector3 p0, Vector3 p1, float t)
|
|||
|
|
{
|
|||
|
|
return Vector3.Lerp(p0, p1, t);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 二阶贝塞尔曲线
|
|||
|
|
public static Vector3 QuadraticBezier(Vector3[] points, float t)
|
|||
|
|
{
|
|||
|
|
if (points.Length != 3) Debug.LogError("需要3个控制点");
|
|||
|
|
|
|||
|
|
float u = 1 - t;
|
|||
|
|
return
|
|||
|
|
u * u * points[0] +
|
|||
|
|
2 * u * t * points[1] +
|
|||
|
|
t * t * points[2];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 三阶贝塞尔曲线
|
|||
|
|
public static Vector3 CubicBezier(Vector3[] points, float t)
|
|||
|
|
{
|
|||
|
|
if (points.Length != 4) Debug.LogError("需要4个控制点");
|
|||
|
|
|
|||
|
|
float u = 1 - t;
|
|||
|
|
return
|
|||
|
|
u * u * u * points[0] +
|
|||
|
|
3 * u * u * t * points[1] +
|
|||
|
|
3 * u * t * t * points[2] +
|
|||
|
|
t * t * t * points[3];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// n阶贝塞尔曲线(通用实现)
|
|||
|
|
public static Vector3 BezierInterpolation(Vector3[] points, float t)
|
|||
|
|
{
|
|||
|
|
if (points.Length < 2)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("至少需要2个控制点");
|
|||
|
|
return Vector3.zero;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Vector3[] temp = new Vector3[points.Length];
|
|||
|
|
points.CopyTo(temp, 0);
|
|||
|
|
|
|||
|
|
// 德卡斯特里奥算法递推
|
|||
|
|
for (int k = 1; k < points.Length; k++)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < points.Length - k; i++)
|
|||
|
|
{
|
|||
|
|
temp[i] = Vector3.Lerp(temp[i], temp[i + 1], t);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return temp[0];
|
|||
|
|
}
|
|||
|
|
}
|