# Fitting planes to Point Clouds

calendar_today

18.10.2023

label

VEX

mouse

Houdini 19.5

### Description

Computing the best fit plane for point clouds using principal component analysis (PCA).

### 1 Code

First, promote the average of all point positons to a detail attribute called `centroid`.

Point Wrangle: Compute Sum

``````vector centroid = detail ( 0, "centroid" );
vector p = v@P - centroid;
setdetailattrib ( geoself ( ), "sumxx", p.x * p.x, "add" );
setdetailattrib ( geoself ( ), "sumxy", p.x * p.y, "add" );
setdetailattrib ( geoself ( ), "sumxz", p.x * p.z, "add" );
setdetailattrib ( geoself ( ), "sumyy", p.y * p.y, "add" );
setdetailattrib ( geoself ( ), "sumyz", p.y * p.z, "add" );
setdetailattrib ( geoself ( ), "sumzz", p.z * p.z, "add" );``````

Detail Wrangle: Compute PCA

``````matrix3 m = set ( @opinput1_sumxx, @opinput1_sumxy, @opinput1_sumxz, @opinput1_sumxy, @opinput1_sumyy, @opinput1_sumyz, @opinput1_sumxz, @opinput1_sumyz, @opinput1_sumzz );

matrix3 u = 0;
vector s = 0;
matrix3 v = 0;

svddecomp ( m, u, s, v );
v = transpose ( v );

vector x = set ( v.xx, v.xy, v.xz );
vector y = set ( v.yx, v.yy, v.yz );
vector z = set ( v.zx, v.zy, v.zz );

vector centroid = v@opinput1_centroid;
int pt = addpoint ( geoself ( ), centroid );

setpointattrib ( geoself ( ), "x", pt, x );
setpointattrib ( geoself ( ), "y", pt, y );
setpointattrib ( geoself ( ), "z", pt, z );

setpointattrib ( geoself ( ), "N", pt, z );``````

### 2 Source

Code published with friendly permission by Yunus "animatrix" Balcioglu, originally published on the SideFX forums:
https://www.sidefx.com/forum/topic/87448/#post-377569

More in-depth VEX training by the same author can be found on https://www.pragmatic-vfx.com/.

### 3 Documentation

Houdini now comes with a built-in PCA-node:
https://www.sidefx.com/docs/houdini/nodes/sop/pca.html