Home > matGeom > geom3d > transformPoint3d.m

transformPoint3d

PURPOSE ^

TRANSFORMPOINT3D Transform a point with a 3D affine transform.

SYNOPSIS ^

function varargout = transformPoint3d(pts, transfo, varargin)

DESCRIPTION ^

TRANSFORMPOINT3D Transform a point with a 3D affine transform.

   PT2 = transformPoint3d(PT1, TRANS);
   PT2 = transformPoint3d(X1, Y1, Z1, TRANS);
   where PT1 has the form [xp yp zp], and TRANS is a 3-by-3, 3-by-4, or
   4-by-4 matrix, returns the point transformed according to the affine
   transform specified by TRANS.

   The function accepts transforms given using the following formats:
   [a b c]   ,   [a b c j] , or [a b c j]
   [d e f]       [d e f k]      [d e f k]
   [g h i]       [g h i l]      [g h i l]
                                [0 0 0 1]

   PT2 = transformPoint3d(PT1, TRANS) 
   also work when PT1 is a N-by-3-by-M-by-P-by-ETC array of double. In
   this case, PT2 has the same size as PT1.

   PT2 = transformPoint3d(X1, Y1, Z1, TRANS);
   also work when X1, Y1 and Z1 are 3 arrays with the same size. In this
   case, PT2 will be a 1-by-3 cell containing {X Y Z} outputs of size(X1).

   [X2, Y2, Z2] = transformPoint3d(...);
   returns the result in 3 different arrays the same size as the input.
   This form can be useful when used with functions like meshgrid or warp.
   
   MESH2 = transformPoint3d(MESH, TRANS) 
   transforms the field 'vertices' of the struct MESH and returns the same
   struct with the transformed vertices.
   (It is recommended to use the function 'transformMesh', within the
   "meshes3d" module). 

   See also:
     points3d, transforms3d, transformMesh, createTranslation3d
     createRotationOx, createRotationOy, createRotationOz, createScaling

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function varargout = transformPoint3d(pts, transfo, varargin)
0002 %TRANSFORMPOINT3D Transform a point with a 3D affine transform.
0003 %
0004 %   PT2 = transformPoint3d(PT1, TRANS);
0005 %   PT2 = transformPoint3d(X1, Y1, Z1, TRANS);
0006 %   where PT1 has the form [xp yp zp], and TRANS is a 3-by-3, 3-by-4, or
0007 %   4-by-4 matrix, returns the point transformed according to the affine
0008 %   transform specified by TRANS.
0009 %
0010 %   The function accepts transforms given using the following formats:
0011 %   [a b c]   ,   [a b c j] , or [a b c j]
0012 %   [d e f]       [d e f k]      [d e f k]
0013 %   [g h i]       [g h i l]      [g h i l]
0014 %                                [0 0 0 1]
0015 %
0016 %   PT2 = transformPoint3d(PT1, TRANS)
0017 %   also work when PT1 is a N-by-3-by-M-by-P-by-ETC array of double. In
0018 %   this case, PT2 has the same size as PT1.
0019 %
0020 %   PT2 = transformPoint3d(X1, Y1, Z1, TRANS);
0021 %   also work when X1, Y1 and Z1 are 3 arrays with the same size. In this
0022 %   case, PT2 will be a 1-by-3 cell containing {X Y Z} outputs of size(X1).
0023 %
0024 %   [X2, Y2, Z2] = transformPoint3d(...);
0025 %   returns the result in 3 different arrays the same size as the input.
0026 %   This form can be useful when used with functions like meshgrid or warp.
0027 %
0028 %   MESH2 = transformPoint3d(MESH, TRANS)
0029 %   transforms the field 'vertices' of the struct MESH and returns the same
0030 %   struct with the transformed vertices.
0031 %   (It is recommended to use the function 'transformMesh', within the
0032 %   "meshes3d" module).
0033 %
0034 %   See also:
0035 %     points3d, transforms3d, transformMesh, createTranslation3d
0036 %     createRotationOx, createRotationOy, createRotationOz, createScaling
0037 %
0038 
0039 %   ---------
0040 %   author : David Legland
0041 %   INRA - TPV URPOI - BIA IMASTE
0042 %   created the 10/02/2005.
0043 %
0044 
0045 %   23/03/2006 add support for non vector point data
0046 %   26/10/2006 better support for large data handling: iterate on points
0047 %       in the case of a memory lack.
0048 %   20/04/2007 add link to rotationXX functions
0049 %   29/09/2010 fix bug in catch case
0050 %   12/03/2011 slightly reduce memory usage
0051 
0052 
0053 %% Parse input arguments
0054 
0055 % Check special case: if first argument is a struct with a field named
0056 % 'vertices', then the output will be the same struct, but with the
0057 % transformed vertices.
0058 if nargin == 2 && isstruct(pts) && isfield(pts, 'vertices')
0059     mesh = pts;
0060     mesh.vertices = transformPoint3d(mesh.vertices, transfo);
0061     varargout = {mesh};
0062     return;
0063 end
0064 
0065 % Parse x, y, and z coordinates of input points from input arguments
0066 if nargin == 2
0067     % Point coordinates are given in a single N-by-3-by-M-by-etc argument.
0068     % Preallocate x, y, and z to size N-by-1-by-M-by-etc, then fill them in
0069     dim = size(pts);
0070     dim(2) = 1;
0071     [x, y, z] = deal(zeros(dim, class(pts)));
0072     x(:) = pts(:,1,:);
0073     y(:) = pts(:,2,:);
0074     z(:) = pts(:,3,:);
0075     
0076 elseif nargin == 4
0077     % Point coordinates are given in 3 different arrays
0078     x = pts;
0079     y = transfo;
0080     z = varargin{1};
0081     transfo = varargin{2};
0082     dim = size(x);
0083     
0084 else
0085     error('MatGeom:geom3d:WrongInputArgumentNumber', ...
0086         'Requires number of input arguments to be either 2 or 4');
0087 end
0088 
0089 
0090 %% Process transformation matrix
0091 
0092 % extract the linear and the translation parts of the matrix
0093 linear = transfo(1:3, 1:3)';
0094 trans = [0 0 0];
0095 if size(transfo, 2) > 3
0096     trans = transfo(1:3, 4)';
0097 end
0098 
0099 
0100 %% Main processing
0101 
0102 % convert coordinates
0103 try
0104     % vectorial processing, if there is enough memory.
0105     % same as:
0106     % res = (transfo * [x(:) y(:) z(:) ones(NP, 1)]')';
0107     res = bsxfun(@plus, [x(:) y(:) z(:)] * linear, trans);
0108     
0109     % Back-fill x,y,z with new result (saves calling costly reshape())
0110     x(:) = res(:,1);
0111     y(:) = res(:,2);
0112     z(:) = res(:,3);
0113     
0114 catch ME
0115     disp(ME.message)
0116     % process each point one by one, writing in existing array
0117     NP = numel(x);
0118     for i = 1:NP
0119         res = [x(i) y(i) z(i)] * linear + trans;
0120         x(i) = res(1);
0121         y(i) = res(2);
0122         z(i) = res(3);
0123     end
0124 end
0125 
0126 % process output arguments
0127 if nargout <= 1
0128     % results are stored in a unique array
0129     if length(dim) > 2 && dim(2) > 1
0130         warning('geom3d:shapeMismatch',...
0131             'Shape mismatch: Non-vector xyz input should have multiple x,y,z output arguments. Cell {x,y,z} returned instead.')
0132         varargout{1} = {x,y,z};
0133     else
0134         varargout{1} = [x y z];
0135     end
0136     
0137 elseif nargout == 3
0138     % results are returned in three array with same size.
0139     varargout = {x, y, z};
0140 end

Generated on Wed 16-Feb-2022 15:10:47 by m2html © 2003-2019