|
| 1 | +# De Boor's Algorithm |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +De Boor's algorithm is a method for evaluating points on a B-spline or NURBS curve. It's a generalization of the de Casteljau algorithm used for Bézier curves. The algorithm recursively computes a point on the B-spline curve for a given parameter value. |
| 6 | + |
| 7 | +## Implementation |
| 8 | + |
| 9 | +Our implementation in `src/core/functional/deBoor.ts` prioritizes readability and understanding over performance. Here's a breakdown of the algorithm: |
| 10 | + |
| 11 | +### Main Function: `deBoor` |
| 12 | + |
| 13 | +```typescript |
| 14 | +export function deBoor( |
| 15 | + controlPoints: Point[], |
| 16 | + knots: number[], |
| 17 | + t: number, |
| 18 | + degree: number |
| 19 | +): Point { |
| 20 | + // ... |
| 21 | +} |
| 22 | +``` |
| 23 | + |
| 24 | +This function takes four parameters: |
| 25 | + |
| 26 | +- controlPoints: An array of control points that define the shape of the B-spline curve. |
| 27 | + |
| 28 | +- knots: An array of knot values that determine how the control points affect the curve. |
| 29 | + |
| 30 | +- t: The parameter value at which to evaluate the curve. |
| 31 | + |
| 32 | +- degree: The degree of the B-spline curve. |
| 33 | + |
| 34 | +The function performs these steps: |
| 35 | + |
| 36 | +1. Finds the knot span index for the given parameter t. |
| 37 | + |
| 38 | +2. Extracts the relevant control points. |
| 39 | + |
| 40 | +3. Calls the recursive De Boor function to compute the final point. |
| 41 | + |
| 42 | +```typescript |
| 43 | +Recursive Function: deBoorRecursive |
| 44 | +function deBoorRecursive( |
| 45 | + points: Point[], |
| 46 | + knots: number[], |
| 47 | + t: number, |
| 48 | + degree: number, |
| 49 | + spanIndex: number, |
| 50 | + r: number |
| 51 | +): Point { |
| 52 | + // ... |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +This function implements the core of de Boor's algorithm. It recursively computes new sets of points, each set getting closer to the final point on the curve. The recursion continues until we reach the degree of the curve. |
| 57 | + |
| 58 | +Parameters: |
| 59 | + |
| 60 | +- points: The current set of points being processed. |
| 61 | + |
| 62 | +- knots, t, degree: Same as in the main function. |
| 63 | + |
| 64 | +- spanIndex: The index of the knot span containing t. |
| 65 | + |
| 66 | +- r: The current recursion depth. |
| 67 | + |
| 68 | +## Helper Functions |
| 69 | + |
| 70 | +1. findKnotSpanIndex: Determines which knot span contains the parameter t. |
| 71 | + |
| 72 | +2. computeAlpha: Calculates the interpolation factor between two knots. |
| 73 | + |
| 74 | +3. interpolate: Performs linear interpolation between two points. |
| 75 | + |
| 76 | +## Mathematical Explanation |
| 77 | + |
| 78 | +De Boor's algorithm is based on the recursive definition of B-spline basis functions. For a B-spline of degree p, we start with p+1 control points and recursively compute new points using linear interpolation. |
| 79 | + |
| 80 | +The key formula is: |
| 81 | + |
| 82 | +$$ d[i,r](t) = (1 - α) _ d[i-1,r-1](t) + α _ d[i,r-1](t) $$ |
| 83 | + |
| 84 | +$d[i,r]$ is the i-th point at recursion level r |
| 85 | + |
| 86 | +$$α = (t - knot[i]) / (knot[i+p-r+1] - knot[i])$$ |
| 87 | + |
| 88 | +This process is repeated p times, resulting in the final point on the curve. |
| 89 | + |
| 90 | +Advantages of This Implementation |
| 91 | + |
| 92 | +- Readability : The recursive approach closely mirrors the mathematical definition, making it easier to understand the algorithm's logic. |
| 93 | + |
| 94 | +- Modularity : Helper functions break down the algorithm into clear, manageable steps. |
| 95 | + |
| 96 | +- Educational Value : This implementation serves as an excellent reference for learning and teaching the algorithm. |
| 97 | + |
| 98 | +## Performance Considerations |
| 99 | + |
| 100 | +While this implementation prioritizes clarity, it's not optimized for performance. For high-performance applications, consider using the optimized version in src/core/optimized/deBoor.ts, which uses techniques like in-place computation and loop unrolling to improve efficiency. |
| 101 | + |
| 102 | +## Key optimizations in this version include: |
| 103 | + |
| 104 | +1. In-place computation : Instead of creating new arrays in each iteration, we use a single working array ( points) and modify it in-place. |
| 105 | + |
| 106 | +2. Loop unrolling : We've unrolled the inner loop for the 2D point calculation, avoiding the need for a separate interpolation function. |
| 107 | + |
| 108 | +3. Efficient knot span search : The knot span index finding is optimized with a simple while loop, and it handles the edge case where t is at the end of the knot vector. |
| 109 | + |
| 110 | +4. Minimized function calls : Helper functions have been inlined to reduce function call overhead. |
| 111 | + |
| 112 | +5. Reduced memory allocation : We only allocate one array ( points) instead of creating new arrays in each recursive step. |
| 113 | + |
| 114 | +6. Direct array access : We use direct array indexing instead of array methods like slice(). |
0 commit comments