Blender  V3.3
FitCurve.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include <cmath>
10 #include <cstdio>
11 #include <cstdlib> // for malloc and free
12 
13 #include "FitCurve.h"
14 
15 using namespace std;
16 
17 namespace Freestyle {
18 
19 using BezierCurve = Vector2 *;
20 
21 /* Forward declarations */
22 static double *Reparameterize(Vector2 *d, int first, int last, double *u, BezierCurve bezCurve);
23 static double NewtonRaphsonRootFind(BezierCurve Q, Vector2 P, double u);
24 static Vector2 BezierII(int degree, Vector2 *V, double t);
25 static double B0(double u);
26 static double B1(double u);
27 static double B2(double u);
28 static double B3(double u);
29 static Vector2 ComputeLeftTangent(Vector2 *d, int end);
30 static double ComputeMaxError(
31  Vector2 *d, int first, int last, BezierCurve bezCurve, double *u, int *splitPoint);
32 static double *ChordLengthParameterize(Vector2 *d, int first, int last);
34  Vector2 *d, int first, int last, double *uPrime, Vector2 tHat1, Vector2 tHat2);
35 static Vector2 V2AddII(Vector2 a, Vector2 b);
36 static Vector2 V2ScaleIII(Vector2 v, double s);
37 static Vector2 V2SubII(Vector2 a, Vector2 b);
38 
39 /* returns squared length of input vector */
40 static double V2SquaredLength(Vector2 *a)
41 {
42  return (((*a)[0] * (*a)[0]) + ((*a)[1] * (*a)[1]));
43 }
44 
45 /* returns length of input vector */
46 static double V2Length(Vector2 *a)
47 {
48  return (sqrt(V2SquaredLength(a)));
49 }
50 
51 static Vector2 *V2Scale(Vector2 *v, double newlen)
52 {
53  double len = V2Length(v);
54  if (len != 0.0) {
55  (*v)[0] *= newlen / len;
56  (*v)[1] *= newlen / len;
57  }
58  return v;
59 }
60 
61 /* return the dot product of vectors a and b */
62 static double V2Dot(Vector2 *a, Vector2 *b)
63 {
64  return (((*a)[0] * (*b)[0]) + ((*a)[1] * (*b)[1]));
65 }
66 
67 /* return the distance between two points */
69 {
70  double dx = (*a)[0] - (*b)[0];
71  double dy = (*a)[1] - (*b)[1];
72  return (sqrt((dx * dx) + (dy * dy)));
73 }
74 
75 /* return vector sum c = a+b */
77 {
78  (*c)[0] = (*a)[0] + (*b)[0];
79  (*c)[1] = (*a)[1] + (*b)[1];
80  return c;
81 }
82 
83 /* normalizes the input vector and returns it */
85 {
86  double len = V2Length(v);
87  if (len != 0.0) {
88  (*v)[0] /= len;
89  (*v)[1] /= len;
90  }
91  return v;
92 }
93 
94 /* negates the input vector and returns it */
96 {
97  (*v)[0] = -(*v)[0];
98  (*v)[1] = -(*v)[1];
99  return v;
100 }
101 
102 /* GenerateBezier:
103  * Use least-squares method to find Bezier control points for region.
104  * Vector2 *d; Array of digitized points
105  * int first, last; Indices defining region
106  * double *uPrime; Parameter values for region
107  * Vector2 tHat1, tHat2; Unit tangents at endpoints
108  */
110  Vector2 *d, int first, int last, double *uPrime, Vector2 tHat1, Vector2 tHat2)
111 {
112  int i;
113  Vector2 A[2]; /* rhs for eqn */
114  int nPts; /* Number of pts in sub-curve */
115  double C[2][2]; /* Matrix C */
116  double X[2]; /* Matrix X */
117  double det_C0_C1; /* Determinants of matrices */
118  double det_C0_X;
119  double det_X_C1;
120  double alpha_l; /* Alpha values, left and right */
121  double alpha_r;
122  Vector2 tmp; /* Utility variable */
123  BezierCurve bezCurve; /* RETURN bezier curve control points. */
124 
125  bezCurve = (Vector2 *)malloc(4 * sizeof(Vector2));
126  nPts = last - first + 1;
127 
128  /* Create the C and X matrices */
129  C[0][0] = 0.0;
130  C[0][1] = 0.0;
131  C[1][0] = 0.0;
132  C[1][1] = 0.0;
133  X[0] = 0.0;
134  X[1] = 0.0;
135  for (i = 0; i < nPts; i++) {
136  /* Compute the A's */
137  A[0] = tHat1;
138  A[1] = tHat2;
139  V2Scale(&A[0], B1(uPrime[i]));
140  V2Scale(&A[1], B2(uPrime[i]));
141 
142  C[0][0] += V2Dot(&A[0], &A[0]);
143  C[0][1] += V2Dot(&A[0], &A[1]);
144  // C[1][0] += V2Dot(&A[0], &A[1]);
145  C[1][0] = C[0][1];
146  C[1][1] += V2Dot(&A[1], &A[1]);
147 
148  tmp = V2SubII(d[first + i],
149  V2AddII(V2ScaleIII(d[first], B0(uPrime[i])),
150  V2AddII(V2ScaleIII(d[first], B1(uPrime[i])),
151  V2AddII(V2ScaleIII(d[last], B2(uPrime[i])),
152  V2ScaleIII(d[last], B3(uPrime[i]))))));
153 
154  X[0] += V2Dot(&A[0], &tmp);
155  X[1] += V2Dot(&A[1], &tmp);
156  }
157 
158  /* Compute the determinants of C and X */
159  det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1];
160  det_C0_X = C[0][0] * X[1] - C[0][1] * X[0];
161  det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1];
162 
163  /* Finally, derive alpha values */
164  if (det_C0_C1 == 0.0) {
165  det_C0_C1 = (C[0][0] * C[1][1]) * 10.0e-12;
166  }
167  alpha_l = det_X_C1 / det_C0_C1;
168  alpha_r = det_C0_X / det_C0_C1;
169 
170  /* If alpha negative, use the Wu/Barsky heuristic (see text) (if alpha is 0, you get coincident
171  * control points that lead to divide by zero in any subsequent NewtonRaphsonRootFind() call).
172  */
173  if (alpha_l < 1.0e-6 || alpha_r < 1.0e-6) {
174  double dist = V2DistanceBetween2Points(&d[last], &d[first]) / 3.0;
175 
176  bezCurve[0] = d[first];
177  bezCurve[3] = d[last];
178  V2Add(&(bezCurve[0]), V2Scale(&(tHat1), dist), &(bezCurve[1]));
179  V2Add(&(bezCurve[3]), V2Scale(&(tHat2), dist), &(bezCurve[2]));
180  return bezCurve;
181  }
182 
183  /* First and last control points of the Bezier curve are positioned exactly at the first and last
184  * data points Control points 1 and 2 are positioned an alpha distance out on the tangent
185  * vectors, left and right, respectively
186  */
187  bezCurve[0] = d[first];
188  bezCurve[3] = d[last];
189  V2Add(&bezCurve[0], V2Scale(&tHat1, alpha_l), &bezCurve[1]);
190  V2Add(&bezCurve[3], V2Scale(&tHat2, alpha_r), &bezCurve[2]);
191  return bezCurve;
192 }
193 
194 /*
195  * Reparameterize:
196  * Given set of points and their parameterization, try to find a better parameterization.
197  * Vector2 *d; Array of digitized points
198  * int first, last; Indices defining region
199  * double *u; Current parameter values
200  * BezierCurve bezCurve; Current fitted curve
201  */
202 static double *Reparameterize(Vector2 *d, int first, int last, double *u, BezierCurve bezCurve)
203 {
204  int nPts = last - first + 1;
205  int i;
206  double *uPrime; /* New parameter values */
207 
208  uPrime = (double *)malloc(nPts * sizeof(double));
209  for (i = first; i <= last; i++) {
210  uPrime[i - first] = NewtonRaphsonRootFind(bezCurve, d[i], u[i - first]);
211  }
212  return uPrime;
213 }
214 
215 /*
216  * NewtonRaphsonRootFind:
217  * Use Newton-Raphson iteration to find better root.
218  * BezierCurve Q; Current fitted curve
219  * Vector2 P; Digitized point
220  * double u; Parameter value for "P"
221  */
222 static double NewtonRaphsonRootFind(BezierCurve Q, Vector2 P, double u)
223 {
224  double numerator, denominator;
225  Vector2 Q1[3], Q2[2]; /* Q' and Q'' */
226  Vector2 Q_u, Q1_u, Q2_u; /* u evaluated at Q, Q', & Q'' */
227  double uPrime; /* Improved u */
228  int i;
229 
230  /* Compute Q(u) */
231  Q_u = BezierII(3, Q, u);
232 
233  /* Generate control vertices for Q' */
234  for (i = 0; i <= 2; i++) {
235  Q1[i][0] = (Q[i + 1][0] - Q[i][0]) * 3.0;
236  Q1[i][1] = (Q[i + 1][1] - Q[i][1]) * 3.0;
237  }
238 
239  /* Generate control vertices for Q'' */
240  for (i = 0; i <= 1; i++) {
241  Q2[i][0] = (Q1[i + 1][0] - Q1[i][0]) * 2.0;
242  Q2[i][1] = (Q1[i + 1][1] - Q1[i][1]) * 2.0;
243  }
244 
245  /* Compute Q'(u) and Q''(u) */
246  Q1_u = BezierII(2, Q1, u);
247  Q2_u = BezierII(1, Q2, u);
248 
249  /* Compute f(u)/f'(u) */
250  numerator = (Q_u[0] - P[0]) * (Q1_u[0]) + (Q_u[1] - P[1]) * (Q1_u[1]);
251  denominator = (Q1_u[0]) * (Q1_u[0]) + (Q1_u[1]) * (Q1_u[1]) + (Q_u[0] - P[0]) * (Q2_u[0]) +
252  (Q_u[1] - P[1]) * (Q2_u[1]);
253 
254  /* u = u - f(u)/f'(u) */
255  if (denominator == 0) { // FIXME
256  return u;
257  }
258  uPrime = u - (numerator / denominator);
259  return uPrime;
260 }
261 
262 /*
263  * Bezier:
264  * Evaluate a Bezier curve at a particular parameter value
265  * int degree; The degree of the bezier curve
266  * Vector2 *V; Array of control points
267  * double t; Parametric value to find point for
268  */
269 static Vector2 BezierII(int degree, Vector2 *V, double t)
270 {
271  int i, j;
272  Vector2 Q; /* Point on curve at parameter t */
273  Vector2 *Vtemp; /* Local copy of control points */
274 
275  /* Copy array */
276  Vtemp = (Vector2 *)malloc((unsigned)((degree + 1) * sizeof(Vector2)));
277  for (i = 0; i <= degree; i++) {
278  Vtemp[i] = V[i];
279  }
280 
281  /* Triangle computation */
282  for (i = 1; i <= degree; i++) {
283  for (j = 0; j <= degree - i; j++) {
284  Vtemp[j][0] = (1.0 - t) * Vtemp[j][0] + t * Vtemp[j + 1][0];
285  Vtemp[j][1] = (1.0 - t) * Vtemp[j][1] + t * Vtemp[j + 1][1];
286  }
287  }
288 
289  Q = Vtemp[0];
290  free((void *)Vtemp);
291  return Q;
292 }
293 
294 /*
295  * B0, B1, B2, B3:
296  * Bezier multipliers
297  */
298 static double B0(double u)
299 {
300  double tmp = 1.0 - u;
301  return (tmp * tmp * tmp);
302 }
303 
304 static double B1(double u)
305 {
306  double tmp = 1.0 - u;
307  return (3 * u * (tmp * tmp));
308 }
309 
310 static double B2(double u)
311 {
312  double tmp = 1.0 - u;
313  return (3 * u * u * tmp);
314 }
315 
316 static double B3(double u)
317 {
318  return (u * u * u);
319 }
320 
321 /*
322  * ComputeLeftTangent, ComputeRightTangent, ComputeCenterTangent:
323  * Approximate unit tangents at endpoints and "center" of digitized curve
324  */
325 /* Vector2 *d; Digitized points
326  * int end; Index to "left" end of region
327  */
328 static Vector2 ComputeLeftTangent(Vector2 *d, int end)
329 {
330  Vector2 tHat1;
331  tHat1 = V2SubII(d[end + 1], d[end]);
332  tHat1 = *V2Normalize(&tHat1);
333  return tHat1;
334 }
335 
336 /* Vector2 *d; Digitized points
337  * int end; Index to "right" end of region
338  */
340 {
341  Vector2 tHat2;
342  tHat2 = V2SubII(d[end - 1], d[end]);
343  tHat2 = *V2Normalize(&tHat2);
344  return tHat2;
345 }
346 
347 /* Vector2 *d; Digitized points
348  * int end; Index to point inside region
349  */
351 {
352  Vector2 V1, V2, tHatCenter;
353 
354  V1 = V2SubII(d[center - 1], d[center]);
355  V2 = V2SubII(d[center], d[center + 1]);
356  tHatCenter[0] = (V1[0] + V2[0]) / 2.0;
357  tHatCenter[1] = (V1[1] + V2[1]) / 2.0;
358  tHatCenter = *V2Normalize(&tHatCenter);
359 
360  /* avoid numerical singularity in the special case when V1 == -V2 */
361  if (V2Length(&tHatCenter) < M_EPSILON) {
362  tHatCenter = *V2Normalize(&V1);
363  }
364 
365  return tHatCenter;
366 }
367 
368 /*
369  * ChordLengthParameterize:
370  * Assign parameter values to digitized points using relative distances between points.
371  * Vector2 *d; Array of digitized points
372  * int first, last; Indices defining region
373  */
374 static double *ChordLengthParameterize(Vector2 *d, int first, int last)
375 {
376  int i;
377  double *u; /* Parameterization */
378 
379  u = (double *)malloc((unsigned)(last - first + 1) * sizeof(double));
380 
381  u[0] = 0.0;
382  for (i = first + 1; i <= last; i++) {
383  u[i - first] = u[i - first - 1] + V2DistanceBetween2Points(&d[i], &d[i - 1]);
384  }
385 
386  for (i = first + 1; i <= last; i++) {
387  u[i - first] = u[i - first] / u[last - first];
388  }
389 
390  return u;
391 }
392 
393 /*
394  * ComputeMaxError :
395  * Find the maximum squared distance of digitized points to fitted curve.
396  * Vector2 *d; Array of digitized points
397  * int first, last; Indices defining region
398  * BezierCurve bezCurve; Fitted Bezier curve
399  * double *u; Parameterization of points
400  * int *splitPoint; Point of maximum error
401  */
402 static double ComputeMaxError(
403  Vector2 *d, int first, int last, BezierCurve bezCurve, double *u, int *splitPoint)
404 {
405  int i;
406  double maxDist; /* Maximum error */
407  double dist; /* Current error */
408  Vector2 P; /* Point on curve */
409  Vector2 v; /* Vector from point to curve */
410 
411  *splitPoint = (last - first + 1) / 2;
412  maxDist = 0.0;
413  for (i = first + 1; i < last; i++) {
414  P = BezierII(3, bezCurve, u[i - first]);
415  v = V2SubII(P, d[i]);
416  dist = V2SquaredLength(&v);
417  if (dist >= maxDist) {
418  maxDist = dist;
419  *splitPoint = i;
420  }
421  }
422  return maxDist;
423 }
424 
426 {
427  Vector2 c;
428  c[0] = a[0] + b[0];
429  c[1] = a[1] + b[1];
430  return c;
431 }
432 
433 static Vector2 V2ScaleIII(Vector2 v, double s)
434 {
435  Vector2 result;
436  result[0] = v[0] * s;
437  result[1] = v[1] * s;
438  return result;
439 }
440 
442 {
443  Vector2 c;
444  c[0] = a[0] - b[0];
445  c[1] = a[1] - b[1];
446  return c;
447 }
448 
449 //------------------------- WRAPPER -----------------------------//
450 
451 FitCurveWrapper::~FitCurveWrapper()
452 {
453  _vertices.clear();
454 }
455 
456 void FitCurveWrapper::DrawBezierCurve(int n, Vector2 *curve)
457 {
458  for (int i = 0; i <= n; ++i) {
459  _vertices.push_back(curve[i]);
460  }
461 }
462 
463 void FitCurveWrapper::FitCurve(vector<Vec2d> &data, vector<Vec2d> &oCurve, double error)
464 {
465  int size = data.size();
466  Vector2 *d = new Vector2[size];
467  for (int i = 0; i < size; ++i) {
468  d[i][0] = data[i][0];
469  d[i][1] = data[i][1];
470  }
471 
472  FitCurve(d, size, error);
473 
474  delete[] d;
475 
476  // copy results
477  for (vector<Vector2>::iterator v = _vertices.begin(), vend = _vertices.end(); v != vend; ++v) {
478  oCurve.emplace_back(v->x(), v->y());
479  }
480 }
481 
482 void FitCurveWrapper::FitCurve(Vector2 *d, int nPts, double error)
483 {
484  Vector2 tHat1, tHat2; /* Unit tangent vectors at endpoints */
485 
486  tHat1 = ComputeLeftTangent(d, 0);
487  tHat2 = ComputeRightTangent(d, nPts - 1);
488  FitCubic(d, 0, nPts - 1, tHat1, tHat2, error);
489 }
490 
491 void FitCurveWrapper::FitCubic(
492  Vector2 *d, int first, int last, Vector2 tHat1, Vector2 tHat2, double error)
493 {
494  BezierCurve bezCurve; /* Control points of fitted Bezier curve */
495  double *u; /* Parameter values for point */
496  double *uPrime; /* Improved parameter values */
497  double maxError; /* Maximum fitting error */
498  int splitPoint; /* Point to split point set at */
499  int nPts; /* Number of points in subset */
500  double iterationError; /* Error below which you try iterating */
501  int maxIterations = 4; /* Max times to try iterating */
502  Vector2 tHatCenter; /* Unit tangent vector at splitPoint */
503  int i;
504 
505  iterationError = error * error;
506  nPts = last - first + 1;
507 
508  /* Use heuristic if region only has two points in it */
509  if (nPts == 2) {
510  double dist = V2DistanceBetween2Points(&d[last], &d[first]) / 3.0;
511 
512  bezCurve = (Vector2 *)malloc(4 * sizeof(Vector2));
513  bezCurve[0] = d[first];
514  bezCurve[3] = d[last];
515  V2Add(&bezCurve[0], V2Scale(&tHat1, dist), &bezCurve[1]);
516  V2Add(&bezCurve[3], V2Scale(&tHat2, dist), &bezCurve[2]);
517  DrawBezierCurve(3, bezCurve);
518  free((void *)bezCurve);
519  return;
520  }
521 
522  /* Parameterize points, and attempt to fit curve */
523  u = ChordLengthParameterize(d, first, last);
524  bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2);
525 
526  /* Find max deviation of points to fitted curve */
527  maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
528  if (maxError < error) {
529  DrawBezierCurve(3, bezCurve);
530  free((void *)u);
531  free((void *)bezCurve);
532  return;
533  }
534 
535  /* If error not too large, try some reparameterization and iteration */
536  if (maxError < iterationError) {
537  for (i = 0; i < maxIterations; i++) {
538  uPrime = Reparameterize(d, first, last, u, bezCurve);
539 
540  free((void *)u);
541  free((void *)bezCurve);
542  u = uPrime;
543 
544  bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2);
545  maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
546 
547  if (maxError < error) {
548  DrawBezierCurve(3, bezCurve);
549  free((void *)u);
550  free((void *)bezCurve);
551  return;
552  }
553  }
554  }
555 
556  /* Fitting failed -- split at max error point and fit recursively */
557  free((void *)u);
558  free((void *)bezCurve);
559  tHatCenter = ComputeCenterTangent(d, splitPoint);
560  FitCubic(d, first, splitPoint, tHat1, tHatCenter, error);
561  V2Negate(&tHatCenter);
562  FitCubic(d, splitPoint, last, tHatCenter, tHat2, error);
563 }
564 
565 } /* namespace Freestyle */
sqrt(x)+1/max(0
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
An Algorithm for Automatically Fitting Digitized Curves by Philip J. Schneider,.
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define X
Definition: GeomUtils.cpp:199
#define C
Definition: RandGen.cpp:25
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Curve curve
int len
Definition: draw_manager.c:108
static float P(float k)
Definition: math_interp.c:25
static void error(const char *str)
Definition: meshlaplacian.c:51
inherits from class Rep
Definition: AppCanvas.cpp:18
static Vector2 BezierII(int degree, Vector2 *V, double t)
Definition: FitCurve.cpp:269
static Vector2 * V2Scale(Vector2 *v, double newlen)
Definition: FitCurve.cpp:51
static double NewtonRaphsonRootFind(BezierCurve Q, Vector2 P, double u)
Definition: FitCurve.cpp:222
static double * Reparameterize(Vector2 *d, int first, int last, double *u, BezierCurve bezCurve)
Definition: FitCurve.cpp:202
static Vector2 V2AddII(Vector2 a, Vector2 b)
Definition: FitCurve.cpp:425
static unsigned c
Definition: RandGen.cpp:83
static double B1(double u)
Definition: FitCurve.cpp:304
static const real M_EPSILON
Definition: Precision.h:15
static Vector2 ComputeRightTangent(Vector2 *d, int end)
Definition: FitCurve.cpp:339
static Vector2 V2ScaleIII(Vector2 v, double s)
Definition: FitCurve.cpp:433
static double V2Dot(Vector2 *a, Vector2 *b)
Definition: FitCurve.cpp:62
static double B0(double u)
Definition: FitCurve.cpp:298
static Vector2 * V2Normalize(Vector2 *v)
Definition: FitCurve.cpp:84
static Vector2 * V2Add(Vector2 *a, Vector2 *b, Vector2 *c)
Definition: FitCurve.cpp:76
static BezierCurve GenerateBezier(Vector2 *d, int first, int last, double *uPrime, Vector2 tHat1, Vector2 tHat2)
Definition: FitCurve.cpp:109
static Vector2 ComputeLeftTangent(Vector2 *d, int end)
Definition: FitCurve.cpp:328
static double V2SquaredLength(Vector2 *a)
Definition: FitCurve.cpp:40
static double * ChordLengthParameterize(Vector2 *d, int first, int last)
Definition: FitCurve.cpp:374
static double B3(double u)
Definition: FitCurve.cpp:316
static double B2(double u)
Definition: FitCurve.cpp:310
static double V2DistanceBetween2Points(Vector2 *a, Vector2 *b)
Definition: FitCurve.cpp:68
static double ComputeMaxError(Vector2 *d, int first, int last, BezierCurve bezCurve, double *u, int *splitPoint)
Definition: FitCurve.cpp:402
static double V2Length(Vector2 *a)
Definition: FitCurve.cpp:46
static Vector2 V2SubII(Vector2 a, Vector2 b)
Definition: FitCurve.cpp:441
static unsigned a[3]
Definition: RandGen.cpp:78
static Vector2 * V2Negate(Vector2 *v)
Definition: FitCurve.cpp:95
static Vector2 ComputeCenterTangent(Vector2 *d, int center)
Definition: FitCurve.cpp:350
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
CCL_NAMESPACE_BEGIN struct Window V