B-Spline Approximations

CS779 Final Project by Kaleb Alway


Download and Usage

Run the executable with ./approx [known_curves] where known_curves is an (optional) file containing B-spline curves in the format outputted by the approx executable.

Click and drag the left mouse button to draw a curve. When the button is released, an approximation to the input curve will be computed and displayed. Use the arrow keys to move the viewport. The View menu allows you to toggle certain display elements. The Optimization menu allows you to customize the algorithm used to approximate the curve. The counters below the menu allow you to adjust parameters of the algorithm (explained later).


Base Project

My base project involved implementing a single B-spline approximation algorithm. This "default" algorithm is the Least Squares distance function paired with uniform parameter selection. These are explained in more detail in the optimization details PDF.


Bonus Features


Manhattan Distance

The default program minimizes the sum of the squared Euclidean distance. I also implemented an algorithm that minimizes the Manhattan distance. See the optimization details


LogSumExp

I also implemented another distance function called LogSumExp, explained in the optimization details.


Chord Length Parameterization

I implemented chord length parameterization as an option instead of uniform parameterization. Again, this is discussed in the optimization details.


Centripetal Parameterization

I also implemented centripetal parameterization. This is a generalization of chord length parameterization. See optimization details.

Below you can see how all of these options perform on a simple input curve.

Least SquaresManhattanLogSumExp
Uniform
Chord Length
Centripetal

All of these look quite good. Generally, centripetal parameterization constructs the best curves. Although it is not shown clearly in these figures, there are cases where each of Least Squares, Manhattan, and LogSumExp produce the "best-looking" curve. However, LogSumExp and Manhattan do not produce exact solutions in my implementation, they are only approximations to the optimal solution. This fact is highlighted when we test a more complex input curve like the one below.

Least SquaresManhattanLogSumExp
Uniform
Chord Length
Centripetal

Known Curves

I implemented a system for saving and loading B-splines so they can be factored into curve approximation. A file containing known curves can be loaded into the program when it is started. At any time, the currently displayed B-spline can be saved to the active known curves with File->Add Known Curve. The set of active known curves can be saved with File->Save Known Curves.

When there are active known curves, a preprocessing step is applied whenever a curve is input by the user. This step attempts to fit each of the known curves to the input curve by scaling, rotating, and paramaterizing them according to some heuristics, and computing how close they are in terms of Euclidean distance. If a known curve is within the user-defined threshold (the "Known Curve Pref" counter in the UI), then the approximation "snaps" to the closest known curve.

The heuristics used to fit the known curves are simple and designed to be quick. In some cases they work reasonably well, as shown below.

In other cases, the results are not very nice. Often, this is because of vastly different parameterization between the input curve and the known curve.


Some Known Curve Libraries

I created two "libraries" of known curves.


Closed Curves

If the endpoint of the input curve is within a certain radius of the beginning point, then the approximation will result in a closed curve.


Cusp Detection and Insertion

My program has an option to automatically detect cusps in the input curve, and insert knots of full multiplicity whenever a cusp is detected. This will allow a cusp to appear in the approximated B-spline.

In theory, this is a nice idea, and the implementation does technically work correctly. However, the results are mixed as shown in the figures below.

With CuspsWithout Cusps

With the cloud shaped input curve, the approximation is clearly improved by detecting cusps. In the second example, some erratic behaviour is happening as certain points near the cusps are being interpolated and the spline segments between these points are tending towards infinity. In cases such as this, it is better not to insert these cusps. The resulting B-spline will often appear to have a cusp regardless, because the control points may be duplicated or the curve may have a loop smaller than 1 pixel in diameter at the cusp point.


Lessons Learned


References and Related Links