Examples | TS
Alignment
Point cloud registration with rigid, OBB, and ICP alignment.
Demonstrates the full alignment pipeline: creating test data with known ground truth, then recovering the transformation using rigid alignment, OBB alignment, and ICP refinement.
Setup: Smoothing and Random Transformation
Load a mesh, smooth it to create a source with known correspondences, then apply a random rigid transformation.
Features Showcased
- Loading STL files with
tf.readStl - Smoothing with
tf.laplacianSmoothed - Random rotations with
tf.makeRandomRotation - NDArray math for point transformation and error computation
Example Code
import * as tf from "@polydera/trueform";
// Load mesh and smooth to create source with known correspondences
const mesh = tf.readStl(buffer);
const smoothed = tf.laplacianSmoothed(mesh, 200, 0.9);
// Random rotation around centroid + large translation
const centroid = tf.mean(smoothed.points, 0);
const R = tf.makeRandomRotation(centroid);
const T = tf.makeTranslation([5, -3, 4]);
const transform = T.matMul(R);
// Apply transformation using NDArray ops
const rot = transform.take([0, 1, 2], [0, 1, 2]); // [3,3] rotation block
const trans = transform.take([0, 1, 2], 3); // [3] translation
const sourcePts = smoothed.points.matMul(rot.T).add(trans);
// RMS error between corresponding points
const diff = mesh.points.sub(sourcePts);
const rms = Math.sqrt(tf.mean(tf.sum(diff.mul(diff), 1)));
Rigid Alignment
Recovers an exact rigid transformation when point correspondences are known (same vertex ordering).
Features Showcased
tf.fitRigidAlignmentwith paired point cloudstf.pointCloudfor wrapping point arrays
Example Code
import * as tf from "@polydera/trueform";
const source = tf.pointCloud(sourcePts);
const target = tf.pointCloud(targetPts);
// Requires 1:1 correspondences (same vertex count and ordering)
const T = tf.fitRigidAlignment(source, target);
console.log("T shape:", T.shape); // [4, 4]
Rigid alignment uses SVD to find the optimal rotation and translation. It requires matched point pairs — if correspondences are unknown, use OBB alignment instead.
OBB Alignment
Aligns point clouds by matching their oriented bounding boxes. No correspondences needed.
Features Showcased
tf.fitObbAlignmentwithout and with tree-based disambiguationsampleSize: 0to use all points for disambiguation
Example Code
import * as tf from "@polydera/trueform";
const source = tf.pointCloud(sourcePts);
const target = tf.pointCloud(targetPts);
// Without disambiguation (fast, may pick wrong OBB orientation)
const T1 = tf.fitObbAlignment(source, target, { sampleSize: 0 });
// With tree-based disambiguation (tests 4 orientations, picks best)
const T2 = tf.fitObbAlignment(source, target);
OBB alignment is inherently ambiguous up to 180° rotations about each box axis. When the target has a spatial tree, the function tests all 4 orientations and picks the one with lowest chamfer distance.
ICP Refinement
Iterative Closest Point refines an initial alignment to sub-smoothing accuracy.
Features Showcased
tf.fitIcpAlignmentwith Point-to-Point and Point-to-Plane modes- Setting initial pose via
source.transformation - Composing delta transforms with
.matMul - Point normals via
mesh.pointNormals
Example Code
import * as tf from "@polydera/trueform";
// Target with normals enables Point-to-Plane ICP
const target = tf.pointCloud(targetPts);
target.normals = mesh.pointNormals;
// Set initial alignment (e.g. from OBB)
const source = tf.pointCloud(sourcePts);
source.transformation = T_obb;
// Point-to-Point ICP
const T_p2p = tf.fitIcpAlignment(source, target, {
maxIterations: 50,
nSamples: 1000,
k: 1,
minRelativeImprovement: 1e-6,
});
// Point-to-Plane ICP (sigma > 0 enables plane mode)
const T_p2l = tf.fitIcpAlignment(source, target, {
maxIterations: 50,
nSamples: 1000,
sigma: 1,
});
// Compose: total = delta @ initial
const T_final = T_p2l.matMul(T_obb);
Point-to-Plane ICP converges faster than Point-to-Point because it allows sliding along surfaces. Set
sigma: 1 and attach normals to the target cloud to enable it.Cross-Resolution Alignment
Align meshes at different resolutions using Chamfer error to evaluate quality.
Features Showcased
tf.chamferErrorfor asymmetric distance measurement- OBB → ICP pipeline across resolutions
- Setting and clearing
transformation
Example Code
import * as tf from "@polydera/trueform";
const highRes = tf.pointCloud(highPts);
const lowRes = tf.pointCloud(lowPts);
// Baseline: Chamfer error when already aligned
const baseline = tf.chamferError(lowRes, highRes);
// Align low-res to high-res
const T_obb = tf.fitObbAlignment(lowRes, highRes);
lowRes.transformation = T_obb;
// Refine with ICP
const T_icp = tf.fitIcpAlignment(lowRes, highRes, {
maxIterations: 50,
nSamples: 1000,
});
lowRes.transformation = T_icp.matMul(T_obb);
const finalError = tf.chamferError(lowRes, highRes);
console.log(`Baseline: ${baseline}, Final: ${finalError}`);
