Home > matGeom > geom3d > orientedBox3d.m

orientedBox3d

PURPOSE ^

ORIENTEDBOX3D Object-oriented bounding box of a set of 3D points.

SYNOPSIS ^

function [box3d, rotMat] = orientedBox3d(pts)

DESCRIPTION ^

ORIENTEDBOX3D Object-oriented bounding box of a set of 3D points.

   OOBB = orientedBox3d(PTS)
   Returns the oriented bounding box of the collection of points in the
   N-by-3 array PTS. The result is given as:
   [XC YC ZC  L W H  PHI THETA PSI]
   where (XC,YC,ZC) corresponds to the center of the box, (L,W,H)
   corresponds to the length, width, and depth of the box, and (PHI,
   THETA, PSI) is the orientation of the box as Euler angles.

   [OOBB, ROT] = orientedBox3d(PTS)
   Also returns the rotation matrix of the point cloud, as a 3-by-3
   numeric array.

   Example
     [v, f] = sphereMesh;
     phi=-360+720*rand; theta=-360+720*rand; psi=-360+720*rand;
     angles = [phi, theta, psi];
     rotMat = eulerAnglesToRotation3d(angles);
     rotMat(1:3,4) = randi([-100,100],3,1);
     scale = [randi([7,9],1,1), randi([4,6],1,1), randi([1,3],1,1)];
     pts = transformPoint3d(bsxfun(@times, v, scale), rotMat);
     box3d = orientedBox3d(pts);
     figure; drawPoint3d(pts, '.'); 
     axis equal; xlabel('x'); ylabel('y'); zlabel('z');
     drawCuboid(box3d, 'FaceColor', 'none');

   See also
     meshes3d, drawCuboid, rotation3dToEulerAngles

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [box3d, rotMat] = orientedBox3d(pts)
0002 %ORIENTEDBOX3D Object-oriented bounding box of a set of 3D points.
0003 %
0004 %   OOBB = orientedBox3d(PTS)
0005 %   Returns the oriented bounding box of the collection of points in the
0006 %   N-by-3 array PTS. The result is given as:
0007 %   [XC YC ZC  L W H  PHI THETA PSI]
0008 %   where (XC,YC,ZC) corresponds to the center of the box, (L,W,H)
0009 %   corresponds to the length, width, and depth of the box, and (PHI,
0010 %   THETA, PSI) is the orientation of the box as Euler angles.
0011 %
0012 %   [OOBB, ROT] = orientedBox3d(PTS)
0013 %   Also returns the rotation matrix of the point cloud, as a 3-by-3
0014 %   numeric array.
0015 %
0016 %   Example
0017 %     [v, f] = sphereMesh;
0018 %     phi=-360+720*rand; theta=-360+720*rand; psi=-360+720*rand;
0019 %     angles = [phi, theta, psi];
0020 %     rotMat = eulerAnglesToRotation3d(angles);
0021 %     rotMat(1:3,4) = randi([-100,100],3,1);
0022 %     scale = [randi([7,9],1,1), randi([4,6],1,1), randi([1,3],1,1)];
0023 %     pts = transformPoint3d(bsxfun(@times, v, scale), rotMat);
0024 %     box3d = orientedBox3d(pts);
0025 %     figure; drawPoint3d(pts, '.');
0026 %     axis equal; xlabel('x'); ylabel('y'); zlabel('z');
0027 %     drawCuboid(box3d, 'FaceColor', 'none');
0028 %
0029 %   See also
0030 %     meshes3d, drawCuboid, rotation3dToEulerAngles
0031 
0032 % ------
0033 % Author: David Legland
0034 % E-mail: david.legland@inrae.fr
0035 % Created: 2015-12-01, using Matlab 8.6.0.267246 (R2015b)
0036 % Copyright 2015-2024 INRA - Cepia Software Platform
0037 
0038 tri = convhulln(pts);
0039 nFaces = size(tri, 1);
0040 
0041 %% identify index of face with smallest width
0042 indMinBreadth = 0;
0043 minBreadth = Inf;
0044 for iFace = 1:nFaces
0045     faceInds = tri(iFace, :);
0046     plane = createPlane(pts(faceInds, :));
0047     
0048     breadth = max(abs(distancePointPlane(pts, plane)));
0049     
0050     if breadth < minBreadth
0051         minBreadth = breadth;
0052         indMinBreadth = iFace;
0053     end
0054 end
0055 
0056 % compute projection on reference plane
0057 refPlane = createPlane(pts(tri(indMinBreadth, :), :));
0058 pts2d = planePosition(projPointOnPlane(pts, refPlane), refPlane);
0059 
0060 % compute 2D OOBB for projected points
0061 box2d = orientedBox(pts2d);
0062 
0063 % extract reference points from planar OOBB: the center, and two direction
0064 % vectors
0065 center2d = box2d(1:2);
0066 L1 = box2d(3);
0067 L2 = box2d(4);
0068 markers2d = [0 0; L1/2 0; 0 L2/2];
0069 
0070 % orient reference points to 2d basis
0071 theta2d = box2d(5);
0072 rot = createRotation(deg2rad(theta2d));
0073 tra = createTranslation(center2d);
0074 transfo = tra * rot;
0075 markers2d = transformPoint(markers2d, transfo);
0076 
0077 % backprojection to 3D space
0078 markers3d = planePoint(refPlane, markers2d);
0079 
0080 % compute 3D vectors and center
0081 centerProj = markers3d(1,:);
0082 v1n = normalizeVector3d(markers3d(2,:) - centerProj);
0083 v2n = normalizeVector3d(markers3d(3,:) - centerProj);
0084 
0085 % compute rotation matrix and convert to Euler Angles
0086 v3n = crossProduct3d(v1n, v2n);
0087 rotMat = [v1n' v2n' v3n'];
0088 boxAngles = rotation3dToEulerAngles(rotMat);
0089 
0090 % create 3D object-oriented bounding box
0091 boxCenter3d = centerProj + v3n * minBreadth/2;
0092 box3d = [boxCenter3d L1 L2 minBreadth boxAngles];

Generated on Thu 21-Nov-2024 11:30:22 by m2html © 2003-2022