Initializing 3D Canvas...

Distortion & ARAP Flattening

4 min read•1 page

ARAP Alternating Minimization:

1. Local SVD Step: Extracts the best-fit pure rotation R_i = V U^T for each triangle/cell. 2. Global Poisson Step: Stitches the rotated local cells together seamlessly by solving a symmetric positive-definite system. 3. Isometric Balance: Minimizes both conformal (shearing) and authalic (area stretch) distortion simultaneously.
python
1import numpy as np
2
3def arap_local_global_step(uv_points, rest_2d_edges, neighbors, cot_weights):
4 """
5 As-Rigid-As-Possible (ARAP) parameterization iteration (Sorkine & Alexa 2007):
6 1. Local Step: Compute best-fit rotation R_i in SO(2) per vertex cell via SVD of S_i.
7 2. Global Step: Update UV positions via cotangent-Laplacian Poisson relaxation.
8 """
9 n = len(uv_points)
10 rotations = []
11 for i in range(n):
12 S_i = np.zeros((2, 2))
13 for j in neighbors[i]:
14 w_ij = cot_weights[i, j]
15 du = uv_points[i] - uv_points[j]
16 dp = rest_2d_edges[i, j]
17 S_i += w_ij * np.outer(dp, du)
18 U, _, Vt = np.linalg.svd(S_i)
19 R_i = Vt.T @ U.T
20 if np.linalg.det(R_i) < 0:
21 Vt[-1, :] *= -1
22 R_i = Vt.T @ U.T
23 rotations.append(R_i)
24
25 new_uv = np.copy(uv_points)
26 for i in range(1, n): # Keep vertex 0 pinned to remove translation drift
27 rhs = np.zeros(2)
28 w_sum = 0.0
29 for j in neighbors[i]:
30 w_ij = cot_weights[i, j]
31 rhs += w_ij * (uv_points[j] + 0.5 * (rotations[i] + rotations[j]) @ rest_2d_edges[i, j])
32 w_sum += w_ij
33 new_uv[i] = rhs / max(w_sum, 1e-12)
34 return new_uv

As-Rigid-As-Possible (ARAP Surface Flattening): Conformal methods preserve angles at the expense of severe area stretching, while equiareal methods preserve area at the cost of shearing. The ARAP algorithm (Sorkine & Alexa 2007) seeks a balanced, near-isometric unrolling by ensuring that every local 1-ring star rotates as rigidly as possible (pure rotation R in SO(2)) into the 2D plane, alternating between local Singular Value Decomposition (SVD) and a global linear Poisson solve.

ARAP Iterations
4.00
2 min read•1 page

Jacobian Singular Value Invariants:

1. Singular Values (σ_1, σ_2): Semi-major and semi-minor axes of Tissot's deformation ellipse. 2. Conformal Condition: σ_1 = σ_2 (circles stay circles, no shear). 3. Authalic Condition: σ_1 · σ_2 = 1 (area of every patch is conserved).
python
1def evaluate_distortion_metrics(jacobian_matrix):
2 """
3 Computes singular values sigma_1 >= sigma_2 of mapping Jacobian J.
4 - Conformal (Angle) Distortion: sigma_1 / sigma_2 >= 1 (1 = zero shear).
5 - Authalic (Area) Distortion: sigma_1 * sigma_2 (1 = zero area stretch).
6 - Isometric (Length) Distortion: (sigma_1 - 1)^2 + (sigma_2 - 1)^2.
7 """
8 U, S, Vt = np.linalg.svd(jacobian_matrix)
9 s1, s2 = S[0], S[1]
10
11 conformal_err = s1 / s2
12 authalic_err = s1 * s2
13 return conformal_err, authalic_err

Conformal vs Authalic (Equiareal) Distortion Metrics: Gauss proved that a surface with non-zero Gaussian curvature cannot be flattened to a plane without distortion. In map projections and UV unwrapping, artists choose which invariant to prioritize:Conformal projections preserve local shapes and orthogonal angles (σ_1 / σ_2 = 1), whileAuthalic projections preserve relative land areas (σ_1 σ_2 = 1).

0=Conformal (Angle), 1=Authalic (Area)
0.00

Related Concepts