using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BezierCurve
{
public enum BezierType
{
/// <summary>
/// 一阶
/// </summary>
line,
/// <summary>
/// 二阶
/// </summary>
Quardatic,
/// <summary>
/// 三阶
/// </summary>
Cubic
}
public Transform[] BezierHandle;
public BezierType type;
public BezierCurve(Transform[] BezierHandle, BezierType type)
{
this.BezierHandle = BezierHandle;
this.type = type;
}
public Vector3 GetCurrentBezier(float t)
{
switch (type)
{
case BezierType.line:
return lineBezier(t);
case BezierType.Quardatic:
return QuardaticBezier(t);
case BezierType.Cubic:
return CubicBezier(t);
default:
return Vector3.zero;
}
}
public void SetCurrentBezier(Transform[] handles)
{
if (handles.Length > BezierHandle.Length)
{
for (int i = 0; i < BezierHandle.Length; i++)
{
BezierHandle[i] = handles[i];
}
}
else
{
for (int i = 0; i < handles.Length; i++)
{
BezierHandle[i] = handles[i];
}
}
}
public void SetCurrentBezier(Transform[] handles, BezierType bezierType)
{
type = bezierType;
SetCurrentBezier(handles);
}
/// <summary>
/// 一阶贝塞尔曲线
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
Vector3 lineBezier(float t)
{
if (BezierHandle.Length < 2) throw new System.Exception("使用一阶贝塞尔曲线必须有两个控制点");
Vector3 a = BezierHandle[0].position;
Vector3 b = BezierHandle[1].position;
return a + (b - a) * t;
}
/// <summary>
/// 二阶贝塞尔曲线
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
Vector3 QuardaticBezier(float t)
{
if (BezierHandle.Length < 3) throw new System.Exception("使用二阶贝塞尔曲线必须有三个控制点");
Vector3 a = BezierHandle[0].position;
Vector3 b = BezierHandle[1].position;
Vector3 c = BezierHandle[2].position;
Vector3 aa = a + (b - a) * t;
Vector3 bb = b + (c - b) * t;
return aa + (bb - aa) * t;
}
/// <summary>
/// 三阶贝塞尔
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
Vector3 CubicBezier(float t)
{
if (BezierHandle.Length < 4) throw new System.Exception("使用三阶贝塞尔曲线必须有四个个控制点");
Vector3 a = BezierHandle[0].position;
Vector3 b = BezierHandle[1].position;
Vector3 c = BezierHandle[2].position;
Vector3 d = BezierHandle[3].position;
Vector3 aa = a + (b - a) * t;
Vector3 bb = b + (c - b) * t;
Vector3 cc = c + (d - c) * t;
Vector3 aaa = aa + (bb - aa) * t;
Vector3 bbb = bb + (cc - bb) * t;
return aaa + (bbb - aaa) * t;
}
public static Vector3 GetlineBezier(Vector3 a, Vector3 b, float t)
{
return a + (b - a) * t;
}
public static Vector3 GetQuardaticBezier(Vector3 a, Vector3 b, Vector3 c, float t)
{
Vector3 aa = a + (b - a) * t;
Vector3 bb = b + (c - b) * t;
return aa + (bb - aa) * t;
}
public static Vector3 GetCubicBezier(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float t)
{
Vector3 aa = a + (b - a) * t;
Vector3 bb = b + (c - b) * t;
Vector3 cc = c + (d - c) * t;
Vector3 aaa = aa + (bb - aa) * t;
Vector3 bbb = bb + (cc - bb) * t;
return aaa + (bbb - aaa) * t;
}
}
参考博文:
【游戏开发进阶】玩转贝塞尔曲线,教你在Unity中画Bezier贝塞尔曲线(二阶、三阶),手把手教你推导公式_linxinfa的专栏-CSDN博客_bezier.method.ac攻略
【游戏开发实战】Unity实现类似GitHub地球射线的效果(LineRenderer | 贝塞尔曲线)_linxinfa的专栏-CSDN博客
|