CS 679 W01 Project - Multiresolution Curves

JoanneMcKinley

For my final project, I implemented a multiresolution curve editor, based on the SIGGRAPH '94 paper by Adam Finkelstein and David Salesin. The framework, acting on an arbitrary endpoint-interpolating cubic B-spline curve, provides a variety of resolution levels via wavelet analysis. Supported operations include smoothing the curve, editing the overall sweep of the curve while preserving its details, continuous levels of smoothing and editing, direct manipulation, colour and size dimensions, and adaptive curve sampling.


User Interface

Screen Shot

The most commonly used controls are on the main screen.

More control is provided through menus.

Filter Bank

The core of this project is implementing the filter bank that takes a high level representation of the cubic B-spline, and breaks it down into successively smaller sets of control points and successively larger sets of detail functions. The filter bank works on an arbitrary number of input control points, but behaviour is most intuitive when there are exactly 2^n + 3 for some non-negative n. Here is an example of smoothing and editing using the filter bank.

Original Top Original input curve (34 control points, level 5).
Original Bottom Same curve sent through filter bank (4 control points, level 0).
Modified Bottom Modified curve (4 control points, level 0).
Modified Top Same curve with detail re-added (34 control points, level 5).

First I specify a bunch of matrices that represent the scaling functions (B-spline basis functions - from Cox-de Boor-Mansfield recursion formula) and the orthogonal wavelets. For decomposition, the problem distills down into successively solving Ax = b linear equations. For this, I used LU decomposition since I have multiple right-hand-sides (6, for x, y, r, g, b, and width). Reconstruction can be done with simpler matrix additions and multiplications.


More Features

Adaptive Curve Sampling

If a cubic B-spline is sampled uniformly in t, the resulting line segments will not typically be of equal length. I implemented adaptive recursive line sampling to remedy this. Essentially I guarantee that no line segment is longer than a certain threshold specified in pixels. This, paired with the ability to tweak the number of samples per control point, provides a gradient between smooth and blocky curves.

Additional Dimensions

Finkelstein and Salesin's original multiresolution framework only supported x and y dimensions. I added colour (r, g, b) and line width (as suggested in their Extensions and future work section). All of the machinery extended readily to these additional dimensions. My goal was to provide the ability to specify calligraphy-like curves.
Calligraphy J My "non-artist" attempt at a calligraphy capital J.

Fractions

The original filter bank only allows for integer-level smoothing and editing, and the change in curve can sometimes be quite dramatic between levels. Clearly "smooth" transitions would be better. I do a variation of (1 - t)*c + t*d interpolation to ascribe meaning to curves at fractional levels. Implementing editing is more difficult, first having to figure out which control points at the integer level are maximally influenced by a change in control point at the fractional level, and doing a more complicated (e.g. non-linear) interpolation.

Joanne 6 Curve at top level 6.
Joanne 4.5 Same image at level 4.5.
Joanne 3.5 Same image at level 3.5.

Direct Manipulation

Direct manipulation by tugging on the curve (at any level of resolution, even fractional) is an alternative to control point manipulation. I simulate scan conversion by finding the closest sampled point (Euclidean distance) to the location the user clicked. The Cox-de Boor-Mansfield recurrence tells which control points influence that particular location, and by how much. I take the pseudoinverse and multiply by the specified delta change (up to 6 dimensions) to get the final change in control points. Since the result of the recurrence typically yields a singular matrix, I couldn't reuse LU decomposition; I had to implement singular value decomposition to calculate the pseudoinverse.


Future Work


References