贝塞尔曲线最近经常接触到,今天研究了一下。
- 原理
关于它的原理,网上有很多。
1.一阶
2.二阶
3.多阶
可以看到,多阶可以慢慢降阶为一阶贝塞尔曲线。
1 //一阶 2 private Vector3 BaseBezier(float t,Vector3 pos0,Vector3 pos1) 3 { 4 return pos0 + t * (pos1-pos0); 5 }
递归,降阶为一阶
1 //n阶 2 private Vector3 BezierPro(float t,params Vector3[] posArray) 3 { 4 int l = posArray.Length; 5 6 if (l == 2) 7 { 8 return BaseBezier(t, posArray[0], posArray[1]); 9 } 10 else 11 { 12 Vector3[] tempArray = new Vector3[l-1]; 13 for (int i = 0; i < l-1; i++) 14 { 15 tempArray[i] = BaseBezier(t, posArray[i], posArray[i + 1]); 16 } 17 return BezierPro(t,tempArray); 18 } 19 20 }
在unity里整合:
1 using UnityEngine; 2 using System.Collections; 3 using System.Linq; 4 [ExecuteInEditMode] 5 public class Bezier : MonoBehaviour { 6 public LineRenderer line; 7 public Transform[] PosArray; 8 9 [Range(0,100)] 10 public int sampleCount; 11 // Use this for initialization 12 void Start () { 13 14 } 15 16 // Update is called once per frame 17 void Update () { 18 SetBezier(); 19 } 20 21 //一阶 22 private Vector3 BaseBezier(float t,Vector3 pos0,Vector3 pos1) 23 { 24 return pos0 + t * (pos1-pos0); 25 } 26 //n阶 27 private Vector3 BezierPro(float t,params Vector3[] posArray) 28 { 29 int l = posArray.Length; 30 31 if (l == 2) 32 { 33 return BaseBezier(t, posArray[0], posArray[1]); 34 } 35 else 36 { 37 Vector3[] tempArray = new Vector3[l-1]; 38 for (int i = 0; i < l-1; i++) 39 { 40 tempArray[i] = BaseBezier(t, posArray[i], posArray[i + 1]); 41 } 42 return BezierPro(t,tempArray); 43 } 44 45 } 46 47 [ContextMenu("设置贝塞尔曲线")] 48 private void SetBezier() 49 { 50 if (PosArray.Length<2) 51 { 52 return; 53 } 54 Vector3[] tempArray = new Vector3[PosArray.Length]; 55 56 for (int i = 0; i < PosArray.Length; i++) 57 { 58 tempArray[i] = PosArray[i].position; 59 } 60 61 line.SetVertexCount(sampleCount); 62 for (int i = 0; i < sampleCount; i++) 63 { 64 line.SetPosition(i, BezierPro( (float)i/(float)sampleCount, tempArray) ); 65 } 66 } 67 }
效果展示