ISTRANSFORM3D Check if input is a affine transformation matrix. A = isTransform3d(TRANS) where TRANS should be a transformation matrix. The function accepts transformations 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] If the transformation matrix should only contain rotation and translation without reflection, scaling, shearing, ... set 'rotation' to true. Default is false. Example rot = ... createRotationOx(rand*2*pi)*... createRotationOy(rand*2*pi)*... createRotationOx(rand*2*pi); trans = rot*createTranslation3d(rand(1,3)); isTransform3d(trans, 'rot', true) See also composeTransforms3d, createBasisTransform3d, recenterTransform3d, transformPoint3d ------ Author: oqilipo Created: 2018-07-08 Copyright 2018
0001 function a = isTransform3d(trans, varargin) 0002 %ISTRANSFORM3D Check if input is a affine transformation matrix. 0003 % 0004 % A = isTransform3d(TRANS) where TRANS should be a transformation matrix. 0005 % The function accepts transformations given using the following formats: 0006 % [a b c] , [a b c j] , or [a b c j] 0007 % [d e f] [d e f k] [d e f k] 0008 % [g h i] [g h i l] [g h i l] 0009 % [0 0 0 1] 0010 % 0011 % If the transformation matrix should only contain rotation and 0012 % translation without reflection, scaling, shearing, ... set 'rotation' 0013 % to true. Default is false. 0014 % 0015 % Example 0016 % rot = ... 0017 % createRotationOx(rand*2*pi)*... 0018 % createRotationOy(rand*2*pi)*... 0019 % createRotationOx(rand*2*pi); 0020 % trans = rot*createTranslation3d(rand(1,3)); 0021 % isTransform3d(trans, 'rot', true) 0022 % 0023 % See also 0024 % composeTransforms3d, createBasisTransform3d, recenterTransform3d, 0025 % transformPoint3d 0026 % 0027 % ------ 0028 % Author: oqilipo 0029 % Created: 2018-07-08 0030 % Copyright 2018 0031 0032 narginchk(1,5) 0033 0034 p = inputParser; 0035 logParValidFunc = @(x) (islogical(x) || isequal(x,1) || isequal(x,0)); 0036 addParameter(p,'rotation', 0, logParValidFunc); 0037 valTol = @(x) validateattributes(x,{'numeric'},{'scalar', '>=',eps(class(trans)), '<=',1}); 0038 addParameter(p,'tolerance', 1e-8, valTol); 0039 parse(p,varargin{:}); 0040 rotation = p.Results.rotation; 0041 tolerance = p.Results.tolerance; 0042 0043 % eventually add null translation 0044 if size(trans, 2) == 3 0045 trans = [trans zeros(size(trans, 1), 1)]; 0046 elseif size(trans, 2) < 3 || size(trans, 2) > 4 0047 a=false; 0048 return 0049 end 0050 0051 % eventually add normalization 0052 if size(trans, 1) == 3 0053 trans = [trans;0 0 0 1]; 0054 elseif size(trans, 1) < 3 || size(trans, 1) > 4 0055 a=false; 0056 return 0057 end 0058 0059 a=true; 0060 0061 % NaN is invalid 0062 if any(isnan(trans(:))) 0063 a=false; 0064 return 0065 end 0066 0067 % Infinity is invalid 0068 if any(isinf(trans(:))) 0069 a=false; 0070 return 0071 end 0072 0073 % trans(4,4) has to be a one 0074 if ~isequal(1, trans(4,4)) 0075 a = false; 0076 return 0077 end 0078 0079 % trans(4,1:3) have to be zeros 0080 if ~isequal(zeros(1,3), trans(4,1:3)) 0081 a = false; 0082 return 0083 end 0084 0085 if rotation 0086 % transpose(trans(1:3,1:3)) * trans(1:3,1:3) has to be eye(3) 0087 if any(abs(eye(3) - (trans(1:3,1:3)'*trans(1:3,1:3))) > tolerance) 0088 a = false; 0089 return; 0090 end 0091 0092 % determinant of trans(1:3) has to be one 0093 if abs(1-det(trans)) > tolerance 0094 a = false; 0095 return 0096 end 0097 end 0098 0099 end 0100