AR + GPS Location  3.0.0
All Classes Namespaces Functions Variables Properties Events Pages
CatmullRomCurve.cs
1 using UnityEngine;
2 
3 namespace ARLocation
4 {
8  public class CatmullRomCurve : Curve
9  {
10  // The control points
11  private Vector3 p0;
12  private Vector3 p1;
13  private Vector3 p2;
14  private Vector3 p3;
15 
16  // The alpha/tension factor
17  private float alpha;
18 
19  // The knots
20  private float t0;
21  private float t1;
22  private float t2;
23  private float t3;
24 
25  // Getters for the knots
26  public float T0 { get { return t0; } }
27  public float T1 { get { return t1; } }
28  public float T2 { get { return t2; } }
29  public float T3 { get { return t3; } }
30 
34  private float length;
35 
39  private float[] sampleParameters;
40 
44  private float[] sampleLengths;
45 
49  private bool isSampleDirty;
50 
54  private int lastSampleSize = 100;
55 
60  public float Alpha
61  {
62  get
63  {
64  return alpha;
65  }
66  set
67  {
68  alpha = value;
69  CalculateKnots();
70 
71  isSampleDirty = true;
72  }
73  }
74 
75  public Vector3 P0
76  {
77  get
78  {
79  return p0;
80  }
81  set
82  {
83  p0 = value;
84  CalculateKnots();
85 
86  isSampleDirty = true;
87  }
88  }
89 
90  public Vector3 P1
91  {
92  get
93  {
94  return p1;
95  }
96  set
97  {
98  p1 = value;
99  CalculateKnots();
100 
101  isSampleDirty = true;
102  }
103  }
104 
105  public Vector3 P2
106  {
107  get
108  {
109  return p2;
110  }
111  set
112  {
113  p2 = value;
114  CalculateKnots();
115 
116  isSampleDirty = true;
117  }
118  }
119 
120  public Vector3 P3
121  {
122  get
123  {
124  return p3;
125  }
126  set
127  {
128  p3 = value;
129  CalculateKnots();
130 
131  isSampleDirty = true;
132  }
133  }
134 
144  public CatmullRomCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float alpha)
145  {
146  this.p0 = p0;
147  this.p1 = p1;
148  this.p2 = p2;
149  this.p3 = p3;
150 
151  this.alpha = alpha;
152 
153  isSampleDirty = true;
154 
155  CalculateKnots();
156  }
157 
158  private void CalculateKnots()
159  {
160  var x = alpha * 0.5f;
161  t0 = 0.0f;
162  t1 = t0 + Mathf.Pow((p1 - p0).sqrMagnitude, x);
163  t2 = t1 + Mathf.Pow((p2 - p1).sqrMagnitude, x);
164  t3 = t2 + Mathf.Pow((p3 - p2).sqrMagnitude, x);
165  }
166 
172  public override Vector3 GetPoint(float u)
173  {
174  u = Mathf.Clamp(u, 0, 1);
175  float t = t1 * (1 - u) + t2 * u;
176 
177  Vector3 a1 = (t1 - t) / (t1 - t0) * p0 + ((t - t0) / (t1 - t0)) * p1;
178  Vector3 a2 = (t2 - t) / (t2 - t1) * p1 + ((t - t1) / (t2 - t1)) * p2;
179  Vector3 a3 = (t3 - t) / (t3 - t2) * p2 + ((t - t2) / (t3 - t2)) * p3;
180 
181  Vector3 b1 = (t2 - t) / (t2 - t0) * a1 + ((t - t0) / (t2 - t0)) * a2;
182  Vector3 b2 = (t3 - t) / (t3 - t1) * a2 + ((t - t1) / (t3 - t1)) * a3;
183 
184  Vector3 c = (t2 - t) / (t2 - t1) * b1 + ((t - t1) / (t2 - t1)) * b2;
185 
186  return c;
187  }
188 
194  public override CurvePointData GetPointAndTangent(float u)
195  {
196  u = Mathf.Clamp(u, 0, 1);
197  float t = t1 * (1 - u) + t2 * u;
198 
199  Vector3 a1 = (t1 - t) / (t1 - t0) * p0 + ((t - t0) / (t1 - t0)) * p1;
200  Vector3 a2 = (t2 - t) / (t2 - t1) * p1 + ((t - t1) / (t2 - t1)) * p2;
201  Vector3 a3 = (t3 - t) / (t3 - t2) * p2 + ((t - t2) / (t3 - t2)) * p3;
202 
203  Vector3 b1 = (t2 - t) / (t2 - t0) * a1 + ((t - t0) / (t2 - t0)) * a2;
204  Vector3 b2 = (t3 - t) / (t3 - t1) * a2 + ((t - t1) / (t3 - t1)) * a3;
205 
206  Vector3 c = (t2 - t) / (t2 - t1) * b1 + ((t - t1) / (t2 - t1)) * b2;
207 
208  Vector3 da1 = (1.0f / (t1 - t0)) * (p1 - p0);
209  Vector3 da2 = (1.0f / (t2 - t1)) * (p2 - p1);
210  Vector3 da3 = (1.0f / (t3 - t2)) * (p3 - p2);
211 
212  Vector3 db1 = (t2 - t) / (t2 - t0) * da1 + ((t - t0) / (t2 - t0)) * da2 +
213  (1.0f / (t2 - t0)) * (a2 - a1);
214  Vector3 db2 = (t3 - t) / (t3 - t1) * da2 + ((t - t1) / (t3 - t1)) * da3 +
215  (1.0f / (t3 - t1)) * (a3 - a2);
216 
217  Vector3 dc = (t2 - t) / (t2 - t1) * db1 + ((t - t1) / (t2 - t1)) * db2 +
218  (1.0f / (t2 - t1)) * (b2 - b1);
219 
220 
221  return new CurvePointData { point = c, tangent = dc };
222  }
223 
230  public override Vector3[] Sample(int n)
231  {
232  lastSampleSize = n;
233 
234  if (n == 0)
235  {
236  return new[] { GetPoint(0), GetPoint(1) };
237  }
238 
239  var sample = new Vector3[n + 2];
240  var delta = 1.0f / (n + 1.0f);
241  length = 0.0f;
242 
243  sampleParameters = new float[n + 2];
244  sampleLengths = new float[n + 2];
245 
246  for (var i = 0; i < (n + 2); i++)
247  {
248  sample[i] = GetPoint(i * delta);
249  sampleParameters[i] = i * delta;
250 
251  if (i > 0)
252  {
253  length += (sample[i] - sample[i - 1]).magnitude;
254  }
255 
256  sampleLengths[i] = length;
257  }
258 
259  isSampleDirty = false;
260 
261  return (Vector3[])sample.Clone();
262  }
263 
269  public override float EstimateLength(int n = 100)
270  {
271  if (isSampleDirty || lastSampleSize != n)
272  {
273  Sample(n);
274  }
275 
276  return length;
277  }
278 
284  public override float GetParameterForLength(float s)
285  {
286  if (isSampleDirty)
287  {
288  Sample(lastSampleSize);
289  }
290 
291  for (var i = 0; i < (sampleParameters.Length - 1); i++)
292  {
293  if (s >= sampleLengths[i] && s <= sampleLengths[i + 1])
294  {
295  var a = (s - sampleLengths[i]) / (sampleLengths[i + 1] - sampleLengths[i]);
296  return (1 - a) * sampleParameters[i] + a * sampleParameters[i + 1];
297  }
298  }
299 
300  return -1.0f;
301  }
302 
308  public override Vector3 GetPointAtLength(float s)
309  {
310  return GetPoint(GetParameterForLength(s));
311  }
312 
320  {
322  }
323  }
324 }
ARLocation.CatmullRomCurve.Alpha
float Alpha
Gets or sets the alpha.
Definition: CatmullRomCurve.cs:61
ARLocation.CatmullRomCurve.GetPointAtLength
override Vector3 GetPointAtLength(float s)
Gets the curve point at a given length.
Definition: CatmullRomCurve.cs:308
ARLocation.CatmullRomCurve
A catmull-rom curve.
Definition: CatmullRomCurve.cs:9
ARLocation.CatmullRomCurve.CatmullRomCurve
CatmullRomCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float alpha)
Creates a catmull-rom curve with control points p0, p1, p2 and p3, and with a given alpha/tension par...
Definition: CatmullRomCurve.cs:144
ARLocation.CatmullRomCurve.EstimateLength
override float EstimateLength(int n=100)
Returns the estimated length.
Definition: CatmullRomCurve.cs:269
ARLocation.CatmullRomCurve.GetPoint
override Vector3 GetPoint(float u)
Calculates the curve at a point u, where u is between 0 and 1.
Definition: CatmullRomCurve.cs:172
ARLocation.CurvePointData
A struct holding a pair of point/tangent values.
Definition: Curve.cs:10
ARLocation.CatmullRomCurve.GetParameterForLength
override float GetParameterForLength(float s)
Gets the curve parameter for a given length.
Definition: CatmullRomCurve.cs:284
ARLocation.CatmullRomCurve.GetPointAndTangentAtLength
override CurvePointData GetPointAndTangentAtLength(float s)
Gets the CurvePointData which stores the point and tangent at a given arc-length.
Definition: CatmullRomCurve.cs:319
ARLocation.Curve
Definition: Curve.cs:17
ARLocation.CatmullRomCurve.Sample
override Vector3[] Sample(int n)
Creates a sample of (N+2) points (i.e., N + start and end points) of the current curve....
Definition: CatmullRomCurve.cs:230
ARLocation.CatmullRomCurve.GetPointAndTangent
override CurvePointData GetPointAndTangent(float u)
Calculates the point and the tangent of the curve.
Definition: CatmullRomCurve.cs:194
ARLocation
Definition: ARLocationConfigInspector.cs:7