为什么我的matlab hgtransform矩阵无效



我试图通过设置MATLAB HGTRANSFORM对象的'Matrix'属性来应用变换矩阵。转换矩阵如下:

 866.0254e-003   500.0000e-003   0.0000e+000   500.0000e-003
 500.0000e-003  -866.0254e-003   0.0000e+000   500.0000e-003
 0.0000e+000     0.0000e+000     1.0000e+000     0.0000e+000
 0.0000e+000     0.0000e+000     0.0000e+000     1.0000e+000

此特定矩阵旨在表示翻译

(0.5,0.5,0)

和围绕pi/6的z轴旋转。

当我尝试这样做时:

% make a unit box
sx = 1;
sy = 1;
sz = 1;
shapeData.Vertices = [ -sx/2, -sy/2, -sz/2;
                        sx/2, -sy/2, -sz/2;
                        sx/2,  sy/2, -sz/2;
                       -sx/2,  sy/2, -sz/2;
                       -sx/2, -sy/2,  sz/2;
                        sx/2, -sy/2,  sz/2;
                        sx/2,  sy/2,  sz/2;
                       -sx/2,  sy/2,  sz/2; ];
shapeData.Faces = [ 1, 4, 3, 2;
                         1, 5, 6, 2;
                         2, 6, 7, 3;
                         7, 8, 4, 3;
                         8, 5, 1, 4;
                         8, 7, 6, 5 ];
figure;
axes;
transformObject = hgtransform (gca);
patchObject = patch (gca, ...
                    'Faces', shapeData.Faces, ...
                    'Vertices', shapeData.Vertices, ...
                    'FaceColor', 'red', ...
                    'FaceAlpha', 1.0, ...
                    'EdgeColor', 'none',        ...
                    'FaceLighting', 'gouraud',     ...
                    'AmbientStrength', 0.15, ...
                    'Parent', transformObject);
M = [ ...
         866.0254e-003   500.0000e-003   0.0000e+000   500.0000e-003; ...
         500.0000e-003  -866.0254e-003   0.0000e+000   500.0000e-003; ...
         0.0000e+000     0.0000e+000     1.0000e+000     0.0000e+000; ...
         0.0000e+000     0.0000e+000     0.0000e+000     1.0000e+000; ...
        ];
set ( transformObject, 'Matrix', M );

我得到错误:

Error using matlab.graphics.primitive.Transform/set
Invalid value for Matrix property

为什么?

编辑

生成变换矩阵的代码。首先,您需要以下构建方向(旋转)矩阵的类:

classdef orientmat
    properties (GetAccess = public, SetAccess = protected)
        orientationMatrix;
    end
    methods
        function this = orientmat (spectype, spec)
        % orentmat constructor
        %
        % Syntax
        %
        % om = orientmat (spectype, spec)
        %
        % Input
        %
        % 
            switch spectype
                case 'orientation'
                    this.orientationMatrix = spec;
                case 'euler'
                    this.orientationMatrix = SpinCalc('EA123toDCM', rad2deg (spec), eps (), 1);
                case 'euler123'
                    this.orientationMatrix = SpinCalc('EA123toDCM', rad2deg (spec), eps (), 1);
                case 'euler321'
                    this.orientationMatrix = SpinCalc('EA321toDCM', rad2deg (spec), eps (), 1);
                case 'vector'
                    % axis and angle (angle in rad = norm of matrix)
                    wcrs = [ 0         spec(3) -spec(2)
                            -spec(3)        0   spec(1)
                             spec(2)  -spec(1)       0] ;   
                    this.orientationMatrix = expm (wcrs);
                case '2vectors'
                    % normalise the fisr vector
                    spec.vec1 = this.unit (spec.vec1);
                    spec.vec2 = this.unit (spec.vec2);
                    spec.vec3 = cross (spec.vec1, spec.vec2);
                    spec.vec2 = this.unit (cross (this.unit (spec.vec3), spec.vec1));
                    switch spec.vec1axis
                        case 1
                            X = spec.vec1;
                            if spec.vec2axis == 2
                                Y = spec.vec2;
                                Z = spec.vec3;
                            elseif spec.vec2axis == 3
                                Y = spec.vec3;
                                Z = spec.vec2;
                            end
                        case 2
                            Y = spec.vec1;
                            if spec.vec2axis == 1
                                X = spec.vec2;
                                Z = spec.vec3;
                            elseif spec.vec2axis == 3
                                X = spec.vec3;
                                Z = spec.vec2;
                            end
                        case 3
                            Z = spec.vec1;
                            if spec.vec2axis == 2
                                X = spec.vec2;
                                Y = spec.vec3;
                            elseif spec.vec2axis == 3
                                X = spec.vec3;
                                Y = spec.vec2;
                            end
                    end
                    this.orientationMatrix = [ X, Y, Z ];
            end 
        end
    end
    % operator overloading
    methods 
        function om = plus (om1, om2)
            om = mbdyn.pre.orientmat ('orientation', om1.orientationMatrix + om2.orientationMatrix);
        end
        function om = minus (om1, om2)
            om = mbdyn.pre.orientmat ('orientation', om1.orientationMatrix - om2.orientationMatrix);
        end
        function om = times (om1, om2)
            om = mbdyn.pre.orientmat ('orientation', om1.orientationMatrix .* om2.orientationMatrix);
        end
        function om = mtimes (om1, om2)
            om = mbdyn.pre.orientmat ('orientation', om1.orientationMatrix * om2.orientationMatrix);
        end
        function om = double (om1)
            om = om1.orientationMatrix;
        end
        function om = uminus (om1)
            om = mbdyn.pre.orientmat ('orientation', -om1.orientationMatrix);
        end
        function om = uplus (om1)
            om = mbdyn.pre.orientmat ('orientation', +om1.orientationMatrix);
        end
        function om = transpose (om1)
            om = mbdyn.pre.orientmat ('orientation', om1.orientationMatrix.');
        end
        function om = ctranspose (om1)
            om = mbdyn.pre.orientmat ('orientation', om1.orientationMatrix');
        end
    end
    methods (Access = private)
        function out = unit (self, vec)
            out = vec ./ norm (vec);
        end
    end

end

然后做:

om = orientmat ('2vectors', struct ('vec1axis', 1, 'vec1', [cos(pi/6);sin(pi/6);0], 'vec2axis', 3, 'vec2', [0;0;1]));
M = [ om.orientationMatrix, [0.5; 0.5; 0]; 0, 0, 0, 1 ];

现在,旋转实际上并不是我打算的问题,但据我所知,它仍然是一个有效的转换矩阵?

答案是matlab仅接受非负缩放术语,请参阅hgtransform支持的转换

最新更新