Guest User

Bezier Curve

a guest
May 31st, 2015
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.12 KB | None | 0 0
  1. using UnityEngine;
  2.  
  3. [System.Serializable]
  4. public class Bezier : System.Object
  5. {
  6.  
  7.     public Vector3 p0;
  8.     public Vector3 p1;
  9.     public Vector3 p2;
  10.     public Vector3 p3;
  11.  
  12.     public float length = 0;
  13.  
  14.     public Vector3[] points;
  15.  
  16.     // Init function v0 = 1st point, v1 = handle of the 1st point , v2 = handle of the 2nd point, v3 = 2nd point
  17.     // handle1 = v0 + v1
  18.     // handle2 = v3 + v2
  19.     public Bezier(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, int _calculatePoints = 0)
  20.     {
  21.         this.p0 = v0;
  22.         this.p1 = v1;
  23.         this.p2 = v2;
  24.         this.p3 = v3;
  25.  
  26.         if (_calculatePoints > 0) CalculatePoints(_calculatePoints);
  27.     }
  28.  
  29.     // 0.0 >= t <= 1.0 her be magic and dragons
  30.     public Vector3 GetPointAtTime(float t)
  31.     {
  32.         float u = 1f - t;
  33.         float tt = t * t;
  34.         float uu = u * u;
  35.         float uuu = uu * u;
  36.         float ttt = tt * t;
  37.  
  38.         Vector3 p = uuu * p0; //first term
  39.         p += 3 * uu * t * p1; //second term
  40.         p += 3 * u * tt * p2; //third term
  41.         p += ttt * p3; //fourth term
  42.  
  43.         return p;
  44.  
  45.     }
  46.  
  47.     //where _num is the desired output of points and _precision is how good we want matching to be
  48.     public void CalculatePoints(int _num, int _precision = 100)
  49.     {
  50.         if (_num > _precision) Debug.LogError("_num must be less than _precision");
  51.  
  52.         //calculate the length using _precision to give a rough estimate, save lengths in array
  53.         length = 0;
  54.         //store the lengths between PointsAtTime in an array
  55.         float[] arcLengths = new float[_precision];
  56.  
  57.         Vector3 oldPoint = GetPointAtTime(0);
  58.  
  59.         for (int p = 1; p < arcLengths.Length; p++)
  60.         {
  61.             Vector3 newPoint = GetPointAtTime((float)p / _precision); //get next point
  62.             arcLengths[p] = Vector3.Distance(oldPoint, newPoint); //find distance to old point
  63.             length += arcLengths[p]; //add it to the bezier's length
  64.             oldPoint = newPoint; //new is old for next loop
  65.         }
  66.  
  67.         //create our points array
  68.         points = new Vector3[_num];
  69.         //target length for spacing
  70.         float segmentLength = length / _num;
  71.  
  72.         //arc index is where we got up to in the array to avoid the Shlemiel error http://www.joelonsoftware.com/articles/fog0000000319.html
  73.         int arcIndex = 0;
  74.  
  75.         float walkLength = 0; //how far along the path we've walked
  76.         oldPoint = GetPointAtTime(0);
  77.  
  78.         //iterate through points and set them
  79.         for (int i = 0; i < points.Length; i++)
  80.         {
  81.             float iSegLength = i * segmentLength; //what the total length of the walkLength must equal to be valid
  82.             //run through the arcLengths until past it
  83.             while (walkLength < iSegLength)
  84.             {
  85.                 walkLength += arcLengths[arcIndex]; //add the next arcLength to the walk
  86.                 arcIndex++; //go to next arcLength
  87.             }
  88.             //walkLength has exceeded target, so lets find where between 0 and 1 it is
  89.             points[i] = GetPointAtTime((float)arcIndex / arcLengths.Length);
  90.  
  91.         }
  92.  
  93.  
  94.     }
  95.  
  96. }
Advertisement
Add Comment
Please, Sign In to add comment