Skip to content

Commit

Permalink
Merge pull request #860 from aerkiaga/faster-bspline
Browse files Browse the repository at this point in the history
Approximate B-spline from a small local neighborhood
  • Loading branch information
ghutchis authored Apr 22, 2022
2 parents 3a69e85 + 0d78f4f commit bb4996e
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions avogadro/rendering/bsplinegeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,28 @@ float B(float i, float k, float t, float knot)
Vector3f BSplineGeometry::computeCurvePoint(
float t, const std::list<Point*>& points) const
{
// degree: line = 1, cuadratic = 2, cube = 3
// degree: linear = 1, quadratic = 2, cubic = 3
float k = 3.0f;
// how many points in either way for approximation
const int lookahead = 10;
// #knot segments = #control points + #degree + 1
float m = points.size() + k + 1.0f;
float m = 2 * lookahead + k + 1.0f;
float knot = 1.0f / m;
Vector3f Q = Vector3f::Zero();
float i = 0.0f;
for (const auto& p : points) {
Q += p->pos * B(i, k, t, knot);
auto it = points.begin();
const auto end = points.end();
size_t size = points.size();
// start from a lookbehind distance rather than at the beginning
int startIndex = (size * t) - lookahead;
if (startIndex < 0) startIndex = 0;
else if (startIndex > size - 2 * lookahead) startIndex = size - 2 * lookahead;
float t2 = (t - startIndex / (float) size) * size / (2 * lookahead);
for (; startIndex > 0 && it != end; --startIndex, ++it) {}
// only read a certain number of elements from here
size_t count = 2 * lookahead;
for (; count && it != end; --count, ++it) {
Q += (*it)->pos * B(i, k, t2, knot);
i += 1.0f;
}
return Q;
Expand Down

0 comments on commit bb4996e

Please sign in to comment.