Bezier curve: improvement of the curve splitting algorithm

bezAt() function needed to be fixed.
Also the convergence in the while loop was sped up and
the break condition was changed.
This commit is contained in:
Mira Grudzinska 2020-10-01 03:09:36 +02:00
parent ea028a479c
commit 9cd4d2b363

View file

@ -110,27 +110,33 @@ float bezAt(const Bezier& bz, float at)
{
auto len = bezLength(bz);
auto biggest = 1.0f;
auto smallest = 0.0f;
auto t = 0.5f;
//just in case to prevent an infinite loop
if (at <= 0) return 0.0f;
if (at >= len) return 1.0f;
at *= 0.5f;
while (true) {
auto right = bz;
Bezier left;
bezSplitLeft(right, at, left);
auto len2 = bezLength(left);
bezSplitLeft(right, t, left);
len = bezLength(left);
if (fabs(len2 - len) < FLT_EPSILON) break;
if (fabs(len - at) < 1e-4 || fabs(smallest - biggest) < FLT_EPSILON) {
break;
}
if (len2 < len) {
at += (biggest - at) * 0.5f;
if (len < at) {
smallest = t;
t = (t + biggest) * 0.5f;
} else {
biggest = at;
at -= (at * 0.5f);
biggest = t;
t = (smallest + t) * 0.5f;
}
}
return at;
return t;
}
@ -141,4 +147,4 @@ void bezSplitAt(const Bezier& cur, float at, Bezier& left, Bezier& right)
bezSplitLeft(right, t, left);
}
}
}