为什么我的Matlab变换矩阵无效?

为什么我的Matlab变换矩阵无效?,matlab,matlab-figure,homogenous-transformation,Matlab,Matlab Figure,Homogenous Transformation,我试图通过设置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+00

我试图通过设置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只接受非负比例项,请参见

您能提供Matlab版本吗?此代码在2014B失败。您有生成转换矩阵的代码吗?@AnderBiguri,它是R2016b,不确定它最早的版本是什么。@Suever我添加了一些代码,您的意思是您的
M
具有负比例项吗。在我看来,
M
只包含旋转和平移。我错过了什么吗?谢谢所以,即使你只想旋转和平移,如果对角线上有项,你也隐含着缩放,或者至少,这似乎是Matlab的想法。也许更准确的说法是Matlab不喜欢变换矩阵对角线上的非负项。谢谢你的回答。对,我也不认为“矩阵的对角线就是缩放矩阵”。考虑一个具有负对角的任意旋转矩阵。显然,它没有进行任何缩放。此外,我注意到,在我的警告中,目标hgtransform矩阵具有正对角线。你还有其他可能的资料可以分享吗?