UnityMol  0.9.6-875
UnityMol viewer / In developement
BSpline.cs
Go to the documentation of this file.
1 using UnityEngine;
2 using System.Collections;
3 
4 public class BSpline {
5  private static int MAX_BEZIER_ORDER = 10; // Maximum curve order.
6 
7  // Control points
8  private float[][] bSplineCPoints;
9 
10  // Parameters
11  bool lookup;
12 
13  // Auxiliary arrays used in the calculations
14  float[][] m3;
15  float[] TVector, DTVector;
16 
17  // Point and tangent vectors
18  float[] pt, tg;
19 
20  private static float[][] BSplineMatrix = new float[][] {
21  new float[] {-1f/6f, 1f/2.0f, -1f/2f, 1f/6f},
22  new float[] { 1f/2f, -1f, 1f/2f, 0f},
23  new float[] {-1f/2f, 0f, 1f/2f, 0f},
24  new float[] { 1f/6f, 2f/3f, 1f/6f, 0f}
25  };
26 
27  // The element(i, n) of this array contains the binomial coefficient
28  // C(i, n) = n!/(i!(n-i)!)
29  private static int[][] BinomialCoefTable = new int[][] {
30  new int[] {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
31  new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
32  new int[] {0, 1, 3, 6, 10, 15, 21, 28, 36, 45},
33  new int[] {0, 0, 1, 4, 10, 20, 35, 56, 84, 120},
34  new int[] {0, 0, 0, 1, 5, 15, 35, 70, 126, 210},
35  new int[] {0, 0, 0, 0, 1, 6, 21, 56, 126, 252},
36  new int[] {0, 0, 0, 0, 0, 1, 7, 28, 84, 210},
37  new int[] {0, 0, 0, 0, 0, 0, 1, 8, 36, 120},
38  new int[] {0, 0, 0, 0, 0, 0, 0, 1, 9, 45},
39  new int[] {0, 0, 0, 0, 0, 0, 0, 0, 1, 10},
40  new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
41  };
42 
43  // The element of this(i, j) of this table contains(i/10)^(3-j).
44  private static float[][] TVectorTable = new float[][] {
45  // t^3, t^2, t^1, t^0
46  new float[] { 0f, 0f, 0f, 1f}, // t = 0.0
47  new float[] {0.001f, 0.01f, 0.1f, 1f}, // t = 0.1
48  new float[] {0.008f, 0.04f, 0.2f, 1f}, // t = 0.2
49  new float[] {0.027f, 0.09f, 0.3f, 1f}, // t = 0.3
50  new float[] {0.064f, 0.16f, 0.4f, 1f}, // t = 0.4
51  new float[] {0.125f, 0.25f, 0.5f, 1f}, // t = 0.5
52  new float[] {0.216f, 0.36f, 0.6f, 1f}, // t = 0.6
53  new float[] {0.343f, 0.49f, 0.7f, 1f}, // t = 0.7
54  new float[] {0.512f, 0.64f, 0.8f, 1f}, // t = 0.8
55  new float[] {0.729f, 0.81f, 0.9f, 1f}, // t = 0.9
56  new float[] { 1f, 1f, 1f, 1f} // t = 1.0
57  };
58 
59 
60 
61 
62  // The element of this(i, j) of this table contains(3-j)*(i/10)^(2-j) if
63  // j < 3, 0 otherwise.
64  private static float[][] DTVectorTable = new float[][] {
65  // 3t^2, 2t^1, t^0
66  new float[] { 0f, 0f, 1f, 0f}, // t = 0.0
67  new float[] {0.03f, 0.2f, 1f, 0f}, // t = 0.1
68  new float[] {0.12f, 0.4f, 1f, 0f}, // t = 0.2
69  new float[] {0.27f, 0.6f, 1f, 0f}, // t = 0.3
70  new float[] {0.48f, 0.8f, 1f, 0f}, // t = 0.4
71  new float[] {0.75f, 1.0f, 1f, 0f}, // t = 0.5
72  new float[] {1.08f, 1.2f, 1f, 0f}, // t = 0.6
73  new float[] {1.47f, 1.4f, 1f, 0f}, // t = 0.7
74  new float[] {1.92f, 1.6f, 1f, 0f}, // t = 0.8
75  new float[] {2.43f, 1.8f, 1f, 0f}, // t = 0.9
76  new float[] { 3f, 2f, 1f, 0f} // t = 1.0
77  };
78 
79  private int Factorial(int n) {
80  if(n <= 0)
81  return 1;
82  else
83  return n * Factorial(n-1);
84  }
85 
86  // Gives n!/(i!(n-i)!).
87  private int BinomialCoef(int i, int n) {
88  if((i <= MAX_BEZIER_ORDER) && (n <= MAX_BEZIER_ORDER))
89  return BinomialCoefTable[i][n-1];
90  else
91  return (int) (Factorial(n) / (Factorial(i) * Factorial(n-i) ) );
92  }
93 
94  // Evaluates the Berstein polinomial(i, n) at u.
95  private float BersteinPol(int i, int n, float u) {
96  return BinomialCoef(i,n) * Mathf.Pow(u,i) * Mathf.Pow(1-u, n-i);
97  }
98 
99  // The derivative of the Berstein polinomial.
100  private float DBersteinPol(int i, int n, float u) {
101  float s1, s2;
102  if(i == 0)
103  s1 = 0;
104  else
105  s1 = i * Mathf.Pow(u, i-1) * Mathf.Pow(1-u, n-i);
106 
107  if(n == i)
108  s2 = 0;
109  else
110  s2 = -(n-i) * Mathf.Pow(u,i) * Mathf.Pow(1-u, n-i-1);
111  return BinomialCoef(i,n) * (s1 + s2);
112  }
113 
114  // Sets lookup table use
115  private void InitParameters(bool t) {
116  TVector = new float[4];
117  DTVector = new float[4];
118  pt = new float[3];
119  tg = new float[3];
120  lookup = t;
121 
122  bSplineCPoints = new float[4][]; // should init 3 columns too
123  for(int i=0; i<4; i++)
124  bSplineCPoints[i] = new float[3];
125 
126  m3 = new float[4][]; // should init 3 columns too
127  for(int i=0; i<4; i++)
128  m3[i] = new float[3];
129  }
130 
131  public BSpline() {
132  InitParameters(true);
133  }
134 
135  public BSpline(bool t) {
136  InitParameters(t);
137  }
138 
139  // Updates the temporal matrix used in 3rd order calculations
140  public void UpdateMatrix3() {
141  float s;
142  int i, j, k;
143  for(i=0; i<4; i++) {
144  for(j=0; j<3; j++) {
145  s = 0;
146  for(k=0; k<4; k++)
147  s += BSplineMatrix[i][k] * bSplineCPoints[k][j];
148  m3[i][j] = s;
149  }
150  }
151  }
152 
153  // Sets n-th control point
154  public void SetCPoint(int n, Vector3 p) {
155  bSplineCPoints[n][0] = p.x;
156  bSplineCPoints[n][1] = p.y;
157  bSplineCPoints[n][2] = p.z;
158  UpdateMatrix3();
159  }
160 
161  // Gets the n-th control point (puts it in p)
162  public void GetCPoint(int n, out Vector3 p) {
163  p.x = bSplineCPoints[n][0];
164  p.y = bSplineCPoints[n][1];
165  p.z = bSplineCPoints[n][2];
166  }
167 
168  // Replaces the current B-spline control points(0, 1, 2) with(1, 2, 3). This
169  // is used when a new spline is to be joined to the recently drawn.
170  public void ShiftBSplineCPoints() {
171  for (int i=0; i<3; i++) {
172  bSplineCPoints[0][i] = bSplineCPoints[1][i];
173  bSplineCPoints[1][i] = bSplineCPoints[2][i];
174  bSplineCPoints[2][i] = bSplineCPoints[3][i];
175  }
176  UpdateMatrix3();
177  }
178 
179 
180 
181  public void CopyCPoints(int n_source, int n_dest) {
182  for (int i=0; i<3; i++)
183  bSplineCPoints[n_dest][i] = bSplineCPoints[n_source][i];
184  }
185 
186  // Gives the point on the cubic spline corresponding to t/10(using the lookup table).
187  private void BSplinePointI(int t) {
188  // Q(u) = TVectorTable[u] * BSplineMatrix * BSplineCPoints
189  float s;
190  int j, k;
191 
192  for(j=0; j<3; j++) {
193  s = 0;
194  for(k=0; k<4; k++){
195  s += TVectorTable[t][k] * m3[k][j];
196  }
197  pt[j] = s;
198  }
199 
200  }
201 
202  // Calculates the point on the cubic spline corresponding to the parameter value t in [0, 1].
203  private void BSplinePoint(float t) {
204  // Q(u) = UVector * BSplineMatrix * BSplineCPoints
205  float s;
206  int i, j, k;
207 
208  for(i=0; i<4; i++)
209  TVector[i] = Mathf.Pow(t, 3-i);
210 
211  for(j=0; j<3; j++) {
212  s = 0;
213  for(k=0; k<4; k++)
214  s += TVector[k] * m3[k][j];
215  pt[j] = s;
216  }
217  }
218 
219  // Calculates the tangent vector of the spline at t.
220  private void BSplineTangent(float t) {
221  // Q(u) = DTVector * BSplineMatrix * BSplineCPoints
222  float s;
223  int i, j, k;
224 
225  for(i=0; i<4; i++) {
226  if (i < 3)
227  DTVector[i] = (3 - i) * Mathf.Pow(t, 2-i);
228  else
229  DTVector[i] = 0f;
230  }
231 
232  for(j=0; j<3; j++) {
233  s = 0;
234  for(k=0; k<4; k++)
235  s += DTVector[k] * m3[k][j];
236  tg[j] = s;
237  }
238  }
239 
240  // Calulates the tangent vector of the spline at t/10.
241  private void BSplineTangentI(int t) {
242  // Q(u) = DTVectorTable[u] * BSplineMatrix * BSplineCPoints
243  float s;
244  int j, k;
245 
246  for(j=0; j<3; j++) {
247  s = 0;
248  for(k=0; k<4; k++)
249  s += DTVectorTable[t][k] * m3[k][j];
250  tg[j] = s;
251  }
252  }
253 
254 
255 
256 
257  private void EvalPoint(float t) {
258  if(lookup)
259  BSplinePointI( (int) (10f * t) );
260  else
261  BSplinePoint(t);
262  }
263 
264  private void EvalTangent(float t) {
265  if(lookup)
266  BSplineTangentI( (int) (10f * t) );
267  else
268  BSplineTangent(t);
269  }
270 
271  public void Feval(float t, out Vector3 p) {
272  EvalPoint(t);
273  p.x = pt[0];
274  p.y = pt[1];
275  p.z = pt[2];
276  }
277 
278  public void Feval2(float t, out Vector3 p) {
279  EvalPoint(t);
280  p.x = Mathf.Pow((1-t), 3)*m3[0][0] + (3*t*Mathf.Pow((1-t),2)*m3[1][0]) + (3*Mathf.Pow(t,2)*((1-t) *m3[2][0])) + (Mathf.Pow(t,3)*m3[3][0]);
281  p.y = Mathf.Pow((1-t), 3)*m3[0][1] + (3*t*Mathf.Pow((1-t),2)*m3[1][1]) + (3*Mathf.Pow(t,2)*((1-t) *m3[2][1])) + (Mathf.Pow(t,3)*m3[3][1]);
282  p.z = Mathf.Pow((1-t), 3)*m3[0][2] + (3*t*Mathf.Pow((1-t),2)*m3[1][2]) + (3*Mathf.Pow(t,2)*((1-t) *m3[2][2])) + (Mathf.Pow(t,3)*m3[3][2]);
283  }
284 
285 
286  public void Deval(float t, out Vector3 d) {
287  EvalTangent(t);
288  d.x = tg[0];
289  d.y = tg[1];
290  d.z = tg[2];
291  }
292 
293  private float FevalX(float t) {
294  EvalPoint(t);
295  return pt[0];
296  }
297 
298  private float FevalY(float t) {
299  EvalPoint(t);
300  return pt[1];
301  }
302 
303  private float FevalZ(float t) {
304  EvalPoint(t);
305  return pt[2];
306  }
307 
308  private float DevalX(float t) {
309  EvalTangent(t);
310  return tg[0];
311  }
312 
313  private float DevalY(float t) {
314  EvalTangent(t);
315  return tg[1];
316  }
317 
318  private float DevalZ(float t) {
319  EvalTangent(t);
320  return tg[2];
321  }
322 
323 
324 }
void ShiftBSplineCPoints()
Definition: BSpline.cs:170
bool lookup
Definition: BSpline.cs:11
static int[][] BinomialCoefTable
Definition: BSpline.cs:29
BSpline(bool t)
Definition: BSpline.cs:135
void GetCPoint(int n, out Vector3 p)
Definition: BSpline.cs:162
float[][] m3
Definition: BSpline.cs:14
void EvalPoint(float t)
Definition: BSpline.cs:257
void Deval(float t, out Vector3 d)
Definition: BSpline.cs:286
void BSplinePointI(int t)
Definition: BSpline.cs:187
float FevalY(float t)
Definition: BSpline.cs:298
static int MAX_BEZIER_ORDER
Definition: BSpline.cs:5
void CopyCPoints(int n_source, int n_dest)
Definition: BSpline.cs:181
float[][] bSplineCPoints
Definition: BSpline.cs:8
int BinomialCoef(int i, int n)
Definition: BSpline.cs:87
int Factorial(int n)
Definition: BSpline.cs:79
float FevalX(float t)
Definition: BSpline.cs:293
void BSplineTangentI(int t)
Definition: BSpline.cs:241
float BersteinPol(int i, int n, float u)
Definition: BSpline.cs:95
float DevalY(float t)
Definition: BSpline.cs:313
static float[][] BSplineMatrix
Definition: BSpline.cs:20
void Feval2(float t, out Vector3 p)
Definition: BSpline.cs:278
void EvalTangent(float t)
Definition: BSpline.cs:264
static float[][] TVectorTable
Definition: BSpline.cs:44
float[] TVector
Definition: BSpline.cs:15
float DevalX(float t)
Definition: BSpline.cs:308
void BSplinePoint(float t)
Definition: BSpline.cs:203
float DBersteinPol(int i, int n, float u)
Definition: BSpline.cs:100
void BSplineTangent(float t)
Definition: BSpline.cs:220
void InitParameters(bool t)
Definition: BSpline.cs:115
void SetCPoint(int n, Vector3 p)
Definition: BSpline.cs:154
float[] tg
Definition: BSpline.cs:18
float[] DTVector
Definition: BSpline.cs:15
float[] pt
Definition: BSpline.cs:18
void Feval(float t, out Vector3 p)
Definition: BSpline.cs:271
float DevalZ(float t)
Definition: BSpline.cs:318
BSpline()
Definition: BSpline.cs:131
void UpdateMatrix3()
Definition: BSpline.cs:140
float FevalZ(float t)
Definition: BSpline.cs:303
static float[][] DTVectorTable
Definition: BSpline.cs:64