为什么我的 Matlab hgtransform 矩阵无效?

Why is my Matlab hgtransform matrix invalid?

我试图通过设置 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

为什么?

编辑

生成变换矩阵的代码。首先你需要以下 class 构造方向(旋转)矩阵:

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 只接受非负缩放项,参见 Transforms Supported by hgtransform