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 % E-mail: david.legland@inrae.fr
0042 % Created: 2005-02-10
0043 % Copyright 2005-2024 INRA - TPV URPOI - BIA IMASTE
0044 
0045 %% Parse input arguments
0046 
0047 % Check special case: if first argument is a struct with a field named
0048 % 'vertices', then the output will be the same struct, but with the
0049 % transformed vertices.
0050 if nargin == 2 && isstruct(pts) && isfield(pts, 'vertices')
0051     mesh = pts;
0052     mesh.vertices = transformPoint3d(mesh.vertices, transfo);
0053     varargout = {mesh};
0054     return;
0055 end
0056 
0057 % Parse x, y, and z coordinates of input points from input arguments
0058 if nargin == 2
0059     % Point coordinates are given in a single N-by-3-by-M-by-etc argument.
0060     % Preallocate x, y, and z to size N-by-1-by-M-by-etc, then fill them in
0061     dim = size(pts);
0062     dim(2) = 1;
0063     [x, y, z] = deal(zeros(dim, class(pts)));
0064     x(:) = pts(:,1,:);
0065     y(:) = pts(:,2,:);
0066     z(:) = pts(:,3,:);
0067     
0068 elseif nargin == 4
0069     % Point coordinates are given in 3 different arrays
0070     x = pts;
0071     y = transfo;
0072     z = varargin{1};
0073     transfo = varargin{2};
0074     dim = size(x);
0075     
0076 else
0077     error('MatGeom:geom3d:WrongInputArgumentNumber', ...
0078         'Requires number of input arguments to be either 2 or 4');
0079 end
0080 
0081 
0082 %% Process transformation matrix
0083 
0084 % extract the linear and the translation parts of the matrix
0085 linear = transfo(1:3, 1:3)';
0086 trans = [0 0 0];
0087 if size(transfo, 2) > 3
0088     trans = transfo(1:3, 4)';
0089 end
0090 
0091 
0092 %% Main processing
0093 
0094 % convert coordinates
0095 try
0096     % vectorial processing, if there is enough memory.
0097     % same as:
0098     % res = (transfo * [x(:) y(:) z(:) ones(NP, 1)]')';
0099     res = bsxfun(@plus, [x(:) y(:) z(:)] * linear, trans);
0100     
0101     % Back-fill x,y,z with new result (saves calling costly reshape())
0102     x(:) = res(:,1);
0103     y(:) = res(:,2);
0104     z(:) = res(:,3);
0105     
0106 catch ME
0107     disp(ME.message)
0108     % process each point one by one, writing in existing array
0109     NP = numel(x);
0110     for i = 1:NP
0111         res = [x(i) y(i) z(i)] * linear + trans;
0112         x(i) = res(1);
0113         y(i) = res(2);
0114         z(i) = res(3);
0115     end
0116 end
0117 
0118 % process output arguments
0119 if nargout <= 1
0120     % results are stored in a unique array
0121     if length(dim) > 2 && dim(2) > 1
0122         warning('geom3d:shapeMismatch',...
0123             'Shape mismatch: Non-vector xyz input should have multiple x,y,z output arguments. Cell {x,y,z} returned instead.')
0124         varargout{1} = {x,y,z};
0125     else
0126         varargout{1} = [x y z];
0127     end
0128     
0129 elseif nargout == 3
0130     % results are returned in three array with same size.
0131     varargout = {x, y, z};
0132 end

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