PRINCIPALAXES Principal axes of a set of ND points. [CENTER, ROTMAT] = principalAxes(PTS) [CENTER, ROTMAT, SCALES] = principalAxes(PTS) Computes the principal axes of a set of points given in a N-by-ND array and returns the result in two or three outputs: CENTER is the centroid of the points, as a 1-by-ND row vector ROTMAT represents the orientation of the point cloud, as a ND-by-ND rotation matrix SCALES is the scaling factor along each dimension, as a 1-by-ND row vector. Example pts = randn(100, 2); pts = transformPoint(pts, createScaling(5, 2)); pts = transformPoint(pts, createRotation(pi/6)); pts = transformPoint(pts, createTranslation(3, 4)); [center, rotMat] = principalAxes(pts); See also equivalentEllipse, equivalentEllipsoid, principalAxesTransform
0001 function varargout = principalAxes(points) 0002 %PRINCIPALAXES Principal axes of a set of ND points. 0003 % 0004 % [CENTER, ROTMAT] = principalAxes(PTS) 0005 % [CENTER, ROTMAT, SCALES] = principalAxes(PTS) 0006 % Computes the principal axes of a set of points given in a N-by-ND array 0007 % and returns the result in two or three outputs: 0008 % CENTER is the centroid of the points, as a 1-by-ND row vector 0009 % ROTMAT represents the orientation of the point cloud, as a ND-by-ND 0010 % rotation matrix 0011 % SCALES is the scaling factor along each dimension, as a 1-by-ND row 0012 % vector. 0013 % 0014 % Example 0015 % pts = randn(100, 2); 0016 % pts = transformPoint(pts, createScaling(5, 2)); 0017 % pts = transformPoint(pts, createRotation(pi/6)); 0018 % pts = transformPoint(pts, createTranslation(3, 4)); 0019 % [center, rotMat] = principalAxes(pts); 0020 % 0021 % See also 0022 % equivalentEllipse, equivalentEllipsoid, principalAxesTransform 0023 % 0024 0025 % ------ 0026 % Author: David Legland 0027 % E-mail: david.legland@inrae.fr 0028 % Created: 2019-08-12, using Matlab 9.6.0.1072779 (R2019a) 0029 % Copyright 2019-2024 INRAE - Cepia Software Platform 0030 0031 % compute centroid of points to estimate center 0032 center = mean(points); 0033 0034 % compute the covariance matrix 0035 covPts = cov(points); 0036 0037 % perform a principal component analysis to extract principal axes 0038 [rotMat, S] = svd(covPts); 0039 0040 % extract length of each semi axis 0041 radii = sqrt(diag(S)); 0042 0043 % sort axes from greater to lower 0044 [radii, ind] = sort(radii, 'descend'); 0045 radii = radii'; 0046 0047 % format U to ensure first axis points to positive x direction 0048 rotMat = rotMat(ind, :); 0049 if rotMat(1,1) < 0 && size(points, 2) > 2 0050 rotMat = -rotMat; 0051 % keep matrix determinant positive 0052 rotMat(:,3) = -rotMat(:,3); 0053 end 0054 0055 % format output 0056 if nargout == 2 0057 varargout = {center, rotMat}; 0058 elseif nargout == 3 0059 varargout = {center, rotMat, radii}; 0060 end