最近研究了曲線繪製的工具,主要是2D方程的繪製。綜合了許多工具,完成了一下兩個腳本。ide
繪製的工具:工具
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 5 public class Curve : MaskableGraphic 6 { 7 public Color color; 8 public float m_LineWidth = 1; 9 [Range(1, 10)] 10 public int Acc = 2; 11 public System.Func<float, float> xConvert = x=>x; 12 public System.Func<float, float> yConvert = y => y; 13 public System.Func<float, float> MainFunc = f => f; 14 protected override void OnPopulateMesh(VertexHelper vh) 15 { 16 var rect = this.rectTransform.rect; 17 vh.Clear(); 18 Debug.Log(rect.xMin); 19 Debug.Log(rect.xMax); 20 Vector2 pos_first = new Vector2(rect.xMin, CalcY(0) * rect.height+rect.yMin); 21 22 for (float x = rect.xMin + Acc; x < rect.xMax; x += Acc) 23 { 24 Vector2 pos = new Vector2(x, CalcY((x - rect.xMin) / rect.width) * rect.height+rect.yMin); 25 var quad = GenerateQuad(pos_first, pos); 26 27 vh.AddUIVertexQuad(quad); 28 29 pos_first = pos; 30 } 31 32 Vector2 pos_last = new Vector2(rect.xMax, CalcY(1) * rect.height+rect.yMin); 33 vh.AddUIVertexQuad(GenerateQuad(pos_first, pos_last)); 34 35 for (int i = 0; i < vh.currentVertCount - 4; i += 4) 36 { 37 vh.AddTriangle(i + 1, i + 2, i + 4); 38 vh.AddTriangle(i + 1, i + 2, i + 7); 39 } 40 Debug.Log("PopulateMesh..." + vh.currentVertCount); 41 } 42 43 //根據曲線組件來計算Y 44 //**** x 爲 (x - rect.xMin) / rect.width) 因此範圍 爲 0~1 45 //返回值 爲y ,取值範圍限定在 0~1; 46 private float CalcY(float x) 47 { 48 return yConvert((MainFunc(xConvert(x)))); 49 } 50 51 private UIVertex[] GenerateQuad(Vector2 pos1, Vector2 pos2) 52 { 53 float dis = Vector2.Distance(pos1, pos2); 54 float y = m_LineWidth * 0.5f * (pos2.x - pos1.x) / dis; 55 float x = m_LineWidth * 0.5f * (pos2.y - pos1.y) / dis; 56 57 if (y <= 0) 58 y = -y; 59 else 60 x = -x; 61 62 UIVertex[] vertex = new UIVertex[4]; 63 64 vertex[0].position = new Vector3(pos1.x + x, pos1.y + y); 65 vertex[1].position = new Vector3(pos2.x + x, pos2.y + y); 66 vertex[2].position = new Vector3(pos2.x - x, pos2.y - y); 67 vertex[3].position = new Vector3(pos1.x - x, pos1.y - y); 68 69 for (int i = 0; i < vertex.Length; i++) 70 { 71 vertex[i].color = color; 72 } 73 74 return vertex; 75 } 76 }
控制腳本:ui
1 using UnityEngine; 2 using System.Collections; 3 using System; 4 [RequireComponent(typeof(Curve))] 5 public class CurveItem : MonoBehaviour { 6 private Curve curve; 7 private Vector2[] posArray; 8 9 //繪製譜圖x 最小值 10 [Header("繪製譜圖x 最小值")] 11 public float xMin; 12 //繪製譜圖 x 最大值 13 [Header("繪製譜圖x 最大值")] 14 public float xMax; 15 //繪製 譜圖 y 最小值 16 [Header("繪製譜圖y 最小值")] 17 public float yMin; 18 //繪製譜圖 y 最大值 19 [Header("繪製譜圖y 最大值")] 20 public float yMax; 21 [Header("繪製譜圖取樣間隔")] 22 public float delta; 23 // Use this for initialization 24 void Start () { 25 curve = this.GetComponentInChildren<Curve>(); 26 } 27 28 29 #region 主要方法 30 31 32 public void ShowPutu(Func<float, float> func) 33 { 34 // DrawLine(LineDrawer.GetSampleArray(func, xMin, xMax, delta)); 35 curve.MainFunc = func; 36 curve.xConvert = MathTool.GetLinear(0, xMin, 1, xMax); 37 curve.yConvert = MathTool.GetLinear(yMin, 0, yMax, 1f); 38 curve.enabled = false; 39 curve.enabled = true; 40 } 41 42 43 44 45 #endregion 46 47 #region Test 48 49 private Func<float, float> func = x=>x*x; 50 51 [ContextMenu("譜圖")] 52 private void Test() 53 { 54 ShowPutu(func); 55 } 56 57 #endregion 58 }
Math工具this
1 2 //獲取線性方程 3 public static Func<float, float> GetLinear(float x0, float y0, float x1, float y1) 4 { 5 Func<float, float> linear = x => 6 { 7 float a = (y1 - y0) / (x1 - x0); 8 return x*a+y0-x0*a; 9 }; 10 return linear; 11 }
調用如下方法便可。spa
ShowPutu(Func<float, float> func)
將兩個腳本都掛載在Canvas下的一個空物體上。3d
演示 x=>x*x:code
演示 x=>Mathf.Asin(x):orm