Bezier curve: improvement of the curve splitting algorithm (#86)

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:
Hermet Park 2020-10-07 14:30:13 +09:00 committed by GitHub
commit e358675d61
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -110,27 +110,33 @@ float bezAt(const Bezier& bz, float at)
{ {
auto len = bezLength(bz); auto len = bezLength(bz);
auto biggest = 1.0f; 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; if (at >= len) return 1.0f;
at *= 0.5f;
while (true) { while (true) {
auto right = bz; auto right = bz;
Bezier left; Bezier left;
bezSplitLeft(right, at, left); bezSplitLeft(right, t, left);
auto len2 = bezLength(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) { if (len < at) {
at += (biggest - at) * 0.5f; smallest = t;
t = (t + biggest) * 0.5f;
} else { } else {
biggest = at; biggest = t;
at -= (at * 0.5f); 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); bezSplitLeft(right, t, left);
} }
} }