29static double B0(
double u);
30static double B1(
double u);
31static double B2(
double u);
32static double B3(
double u);
46 return (((*a)[0] * (*a)[0]) + ((*a)[1] * (*a)[1]));
59 (*v)[0] *= newlen /
len;
60 (*v)[1] *= newlen /
len;
68 return (((*a)[0] * (*
b)[0]) + ((*a)[1] * (*
b)[1]));
74 double dx = (*a)[0] - (*b)[0];
75 double dy = (*a)[1] - (*b)[1];
76 return sqrt((dx * dx) + (dy * dy));
82 (*c)[0] = (*a)[0] + (*b)[0];
83 (*c)[1] = (*a)[1] + (*b)[1];
130 nPts = last - first + 1;
139 for (i = 0; i < nPts; i++) {
146 C[0][0] +=
V2Dot(&A[0], &A[0]);
147 C[0][1] +=
V2Dot(&A[0], &A[1]);
150 C[1][1] +=
V2Dot(&A[1], &A[1]);
158 X[0] +=
V2Dot(&A[0], &tmp);
159 X[1] +=
V2Dot(&A[1], &tmp);
163 det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1];
164 det_C0_X = C[0][0] *
X[1] - C[0][1] *
X[0];
165 det_X_C1 =
X[0] * C[1][1] -
X[1] * C[0][1];
168 if (det_C0_C1 == 0.0) {
169 det_C0_C1 = (C[0][0] * C[1][1]) * 10.0e-12;
171 alpha_l = det_X_C1 / det_C0_C1;
172 alpha_r = det_C0_X / det_C0_C1;
177 if (alpha_l < 1.0e-6 || alpha_r < 1.0e-6) {
180 bezCurve[0] = d[first];
181 bezCurve[3] = d[last];
182 V2Add(&(bezCurve[0]),
V2Scale(&(tHat1), dist), &(bezCurve[1]));
183 V2Add(&(bezCurve[3]),
V2Scale(&(tHat2), dist), &(bezCurve[2]));
191 bezCurve[0] = d[first];
192 bezCurve[3] = d[last];
193 V2Add(&bezCurve[0],
V2Scale(&tHat1, alpha_l), &bezCurve[1]);
194 V2Add(&bezCurve[3],
V2Scale(&tHat2, alpha_r), &bezCurve[2]);
208 int nPts = last - first + 1;
212 uPrime = (
double *)malloc(nPts *
sizeof(
double));
213 for (i = first; i <= last; i++) {
228 double numerator, denominator;
238 for (i = 0; i <= 2; i++) {
239 Q1[i][0] = (Q[i + 1][0] - Q[i][0]) * 3.0;
240 Q1[i][1] = (Q[i + 1][1] - Q[i][1]) * 3.0;
244 for (i = 0; i <= 1; i++) {
245 Q2[i][0] = (Q1[i + 1][0] - Q1[i][0]) * 2.0;
246 Q2[i][1] = (Q1[i + 1][1] - Q1[i][1]) * 2.0;
254 numerator = (Q_u[0] -
P[0]) * (Q1_u[0]) + (Q_u[1] -
P[1]) * (Q1_u[1]);
255 denominator = (Q1_u[0]) * (Q1_u[0]) + (Q1_u[1]) * (Q1_u[1]) + (Q_u[0] -
P[0]) * (Q2_u[0]) +
256 (Q_u[1] -
P[1]) * (Q2_u[1]);
259 if (denominator == 0) {
262 uPrime = u - (numerator / denominator);
281 for (i = 0; i <= degree; i++) {
286 for (i = 1; i <= degree; i++) {
287 for (j = 0; j <= degree - i; j++) {
288 Vtemp[j][0] = (1.0 - t) * Vtemp[j][0] + t * Vtemp[j + 1][0];
289 Vtemp[j][1] = (1.0 - t) * Vtemp[j][1] + t * Vtemp[j + 1][1];
302static double B0(
double u)
304 double tmp = 1.0 - u;
305 return (tmp * tmp * tmp);
308static double B1(
double u)
310 double tmp = 1.0 - u;
311 return (3 * u * (tmp * tmp));
314static double B2(
double u)
316 double tmp = 1.0 - u;
317 return (3 * u * u * tmp);
320static double B3(
double u)
335 tHat1 =
V2SubII(d[end + 1], d[end]);
346 tHat2 =
V2SubII(d[end - 1], d[end]);
358 V1 =
V2SubII(d[center - 1], d[center]);
359 V2 =
V2SubII(d[center], d[center + 1]);
360 tHatCenter[0] = (V1[0] + V2[0]) / 2.0;
361 tHatCenter[1] = (V1[1] + V2[1]) / 2.0;
383 u = (
double *)malloc(
uint(last - first + 1) *
sizeof(
double));
386 for (i = first + 1; i <= last; i++) {
390 for (i = first + 1; i <= last; i++) {
391 u[i - first] = u[i - first] / u[last - first];
415 *splitPoint = (last - first + 1) / 2;
417 for (i = first + 1; i < last; i++) {
421 if (dist >= maxDist) {
440 result[0] =
v[0] * s;
441 result[1] =
v[1] * s;
462 for (
int i = 0; i <= n; ++i) {
463 _vertices.push_back(curve[i]);
469 int size = data.size();
471 for (
int i = 0; i <
size; ++i) {
472 d[i][0] = data[i][0];
473 d[i][1] = data[i][1];
481 for (vector<Vector2>::iterator
v = _vertices.begin(), vend = _vertices.end();
v != vend; ++
v) {
482 oCurve.emplace_back(
v->x(),
v->y());
504 double iterationError;
505 int maxIterations = 4;
510 nPts = last - first + 1;
517 bezCurve[0] = d[first];
518 bezCurve[3] = d[last];
519 V2Add(&bezCurve[0],
V2Scale(&tHat1, dist), &bezCurve[1]);
520 V2Add(&bezCurve[3],
V2Scale(&tHat2, dist), &bezCurve[2]);
522 free((
void *)bezCurve);
532 if (maxError <
error) {
535 free((
void *)bezCurve);
540 if (maxError < iterationError) {
541 for (i = 0; i < maxIterations; i++) {
545 free((
void *)bezCurve);
551 if (maxError <
error) {
554 free((
void *)bezCurve);
562 free((
void *)bezCurve);
void BLI_kdtree_nd_ free(KDTree *tree)
typedef double(DMatrix)[4][4]
An Algorithm for Automatically Fitting Digitized Curves by Philip J. Schneider,.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void DrawBezierCurve(int n, Vector2 *curve)
void FitCubic(Vector2 *d, int first, int last, Vector2 tHat1, Vector2 tHat2, double error)
void FitCurve(std::vector< Vec2d > &data, std::vector< Vec2d > &oCurve, double error)
local_group_size(16, 16) .push_constant(Type b
static void error(const char *str)
static Vector2 BezierII(int degree, Vector2 *V, double t)
static double NewtonRaphsonRootFind(BezierCurve Q, Vector2 P, double u)
static Vector2 * V2Normalize(Vector2 *v)
static double * Reparameterize(Vector2 *d, int first, int last, double *u, BezierCurve bezCurve)
static Vector2 * V2Negate(Vector2 *v)
static Vector2 V2AddII(Vector2 a, Vector2 b)
static double B1(double u)
static const real M_EPSILON
static Vector2 ComputeRightTangent(Vector2 *d, int end)
static Vector2 * V2Add(Vector2 *a, Vector2 *b, Vector2 *c)
static Vector2 V2ScaleIII(Vector2 v, double s)
static double V2Dot(Vector2 *a, Vector2 *b)
static double B0(double u)
static BezierCurve GenerateBezier(Vector2 *d, int first, int last, double *uPrime, Vector2 tHat1, Vector2 tHat2)
static Vector2 ComputeLeftTangent(Vector2 *d, int end)
static Vector2 * V2Scale(Vector2 *v, double newlen)
static double V2SquaredLength(Vector2 *a)
static double * ChordLengthParameterize(Vector2 *d, int first, int last)
static double B3(double u)
static double B2(double u)
static double V2DistanceBetween2Points(Vector2 *a, Vector2 *b)
static double ComputeMaxError(Vector2 *d, int first, int last, BezierCurve bezCurve, double *u, int *splitPoint)
static double V2Length(Vector2 *a)
static Vector2 V2SubII(Vector2 a, Vector2 b)
static Vector2 ComputeCenterTangent(Vector2 *d, int center)
CCL_NAMESPACE_BEGIN struct Window V