# How to animate isometric unwrapping of a curve

A while ago I was thinking about how to illustrate the input data in Shape from sensors — in 2D, the input is the unit tangent field parametrized by arc-length.

I ended with this cool-looking isometric and isotopic unwrapping.

*Move the slider to unwrap the curve. You can also play around in fullscreen.*

The effect is achieved by interpolating between the input curve and a straight line with the same length in the tangent space (using spherical linear interpolation).

I did my original implementation in Matlab; for this post, I wanted to try out doing the same thing in-browser using geometry-processing-js (I actually only use the linear algebra package).

The idea for computing the intermediate curve $\gamma$ is to interpolate between the source tangent field $\mathrm T_0$ (of the original curve) and the target tangent field $\mathrm T_1$ (of the straight line).

\[T(t) = \text{Slerp}(\mathrm T_0,\mathrm T_1,t)\]The in-between tangent field $\mathrm T$ is then integrated by solving a Poisson problem.

\[\Delta \gamma = \nabla \cdot \mathrm T\]In code, this simply translates to

```
// A contains the Cholesky factorization of the Laplacian matrix
const X = A.solvePositiveDefinite(B);
```

The nice thing about this approach is that the Laplacian matrix can be build and pre-factored *once*, prior to the choice of $t$ and computation of the right-hand side `B`

of the system.

```
// nv-2 is the number of (unknown) inner vertices
// ew contains edge weights for the Laplacian (inverse edge lengths)
var buildLaplacian = function() {
// build triplets (w,i,j)
let wij = new Triplet(nv-2,nv-2);
// loop over rows
for (let r=0; r<nv-2; r++){
// cols
let c0 = r-1;
let c1 = r;
let c2 = r+1;
// weights
let w0 = -ew[c1];
let w1 = +ew[c1]+ew[c2];
let w2 = -ew[c2];
wij.addEntry(w1,r,c1);
if (r > 0) wij.addEntry(w0,r,c0);
if (r < nv-3) wij.addEntry(w2,r,c2);
}
// Laplacian : build from triplets
const A = SparseMatrix.fromTriplet(wij);
// return the Cholesky factorization
return A.chol();
}
```

Since the curve is open, we need boundary constraints: I fix the starting point to $[0,0]$ and the endpoint to $(1-t) P + t [L,0]$ with $P$ being the endpoint of the original curve.

Details of the discretization are in *“Robust Fairing via Conformal Curvature Flow” [Crane et al. 2013]*.