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];
|
||
}
|
||
} |