毫無狀態的度過一段時間,今天把貝塞爾曲線實現吧。之前自己推導了一階,二階,三階的貝塞爾方程式,接下來只需要將其實現就好。
在網上找了文章截了兩張圖(一階和二階):
貝塞爾一階.png
貝塞爾二階.png
三階(沒找到,明天上傳自己推導的吧)
還有可以參考雨松大神的文章(PS:但是好像有點錯誤)
鏈接:http://www.xuanyusong.com/archives/1548
接下來就是三階的代碼:
using UnityEngine;
[System.Serializable]
public class Bezier : System.Object
{
//定義四個點,起點終點,兩個控制點
public Vector3 p0;
public Vector3 p1;
public Vector3 p2;
public Vector3 p3;
public float ti = 0f;
//定義幾個私有的向量來存儲那些點
private Vector3 b0 = Vector3.zero;
private Vector3 b1 = Vector3.zero;
private Vector3 b2 = Vector3.zero;
private Vector3 b3 = Vector3.zero;
//四個點之間的三個比例點的坐標
private float Ax;
private float Ay;
private float Az;
private float Bx;
private float By;
private float Bz;
private float Cx;
private float Cy;
private float Cz;
//初始化這四個點
public Bezier(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3)
{
this.p0 = v0;
this.p1 = v1;
this.p2 = v2;
this.p3 = v3;
}
// 0.0 >= t <= 1.0
//獲取t時刻的點
public Vector3 GetPointAtTime(float t)
{
this.CheckConstant();
float t2 = t * t;
float t3 = t * t * t;
float x = this.Ax * t3 + this.Bx * t2 + this.Cx * t + p0.x;
float y = this.Ay * t3 + this.By * t2 + this.Cy * t + p0.y;
float z = this.Az * t3 + this.Bz * t2 + this.Cz * t + p0.z;
return new Vector3(x, y, z);
}
private void SetConstant()
{
this.Cx = 3f * (this.p1.x - this.p0.x);
this.Bx = 3f * (this.p2.x - this.p1.x) - this.Cx;
this.Ax = this.p3.x - this.p0.x - this.Cx - this.Bx;
this.Cy = 3f * (this.p1.y - this.p0.y);
this.By = 3f * (this.p2.y - this.p1.y) - this.Cy;
this.Ay = this.p3.y - this.p0.y - this.Cy - this.By;
this.Cz = 3f * (this.p1.z- this.p0.z);
this.Bz = 3f * (this.p2.z - this.p1.z) - this.Cz;
this.Az = this.p3.z - this.p0.z - this.Cz - this.Bz;
}
// Check if p0, p1, p2 or p3 have changed
private void CheckConstant()
{
if (this.p0 != this.b0 || this.p1 != this.b1 || this.p2 != this.b2 || this.p3 != this.b3)
{
this.SetConstant();
this.b0 = this.p0;
this.b1 = this.p1;
this.b2 = this.p2;
this.b3 = this.p3;
}
}
}
這個實際上是在雨松大神的基礎上修正的(PS:微笑臉),但是重要的貝塞爾的理解(PS:微笑臉)