using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// 贝塞尔曲线
///
[Serializable]
public class BezierCurve
{
///
/// 段数
///
[Range(1, 100)] public int segments = 10;
///
/// 是否循环
///
public bool loop;
///
/// 点集合
///
public List points = new List(2)
{
new BezierCurvePoint() { position = Vector3.back * 5f, tangent = Vector3.back * 5f + Vector3.left * 3f },
new BezierCurvePoint() { position = Vector3.forward * 5f, tangent = Vector3.forward * 5f + Vector3.right * 3f }
};
///
/// 根据归一化位置值获取对应的贝塞尔曲线上的点
///
/// 归一化位置值 [0,1]
///
public Vector3 EvaluatePosition(float t)
{
Vector3 retVal = Vector3.zero;
if (points.Count > 0)
{
float max = points.Count - 1 < 1 ? 0 : (loop ? points.Count : points.Count - 1);
float standardized = (loop && max > 0) ? ((t %= max) + (t < 0 ? max : 0)) : Mathf.Clamp(t, 0, max);
int rounded = Mathf.RoundToInt(standardized);
int i1, i2;
if (Mathf.Abs(standardized - rounded) < Mathf.Epsilon)
i1 = i2 = (rounded == points.Count) ? 0 : rounded;
else
{
i1 = Mathf.FloorToInt(standardized);
if (i1 >= points.Count)
{
standardized -= max;
i1 = 0;
}
i2 = Mathf.CeilToInt(standardized);
i2 = i2 >= points.Count ? 0 : i2;
}
retVal = i1 == i2 ? points[i1].position : BezierCurveUtility.Bezier3(points[i1].position,
points[i1].position + points[i1].tangent, points[i2].position
- points[i2].tangent, points[i2].position, standardized - i1);
}
return retVal;
}
}
[Serializable]
public struct BezierCurvePoint
{
///
/// 坐标点
///
public Vector3 position;
///
/// 控制点 与坐标点形成切线
///
public Vector3 tangent;
}
public class BezierCurveUtility
{
///
/// 三阶贝塞尔曲线
///
/// 起点
/// 控制点1
/// 控制点2
/// 终点
/// [0,1]
///
public static Vector3 Bezier3(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
Vector3 p0p1 = (1 - t) * p0 + t * p1;
Vector3 p1p2 = (1 - t) * p1 + t * p2;
Vector3 p2p3 = (1 - t) * p2 + t * p3;
Vector3 p0p1p2 = (1 - t) * p0p1 + t * p1p2;
Vector3 p1p2p3 = (1 - t) * p1p2 + t * p2p3;
return (1 - t) * p0p1p2 + t * p1p2p3;
}
}