Asked by Richard Crozier
on 22 Feb 2017

I am attempting to apply a transform matrix by setting the 'Matrix' property of a matlab hgtransform object. The transform matrix is below:

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

This particular matrix is intended to represent a translation

(0.5, 0.5, 0)

and rotation around the Z axis of pi/6 (although actually I think it results in a rotation of -pi/6, more on this below).

When I try to do this:

% 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 );

I get the error:

Error using matlab.graphics.primitive.Transform/set

Invalid value for Matrix property

Why?

To generate this transform matrix I used the following class I created which constructs orientation (rotation) matrices in various ways:

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

Then did:

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 ];

This constructs an orientation matrix from two vectors which define a plane.

Now there may be an issue with the rotation not actually being what I intend (I think the order of the cross products is wrong so the rotation ends up in the wrong direction), but as far as I can see it is still a valid transformation matrix. So why does hgtransform not like it?

EDIT

As explained earlier, there is actually an issue with the transform not doing what I intend (actually produces a rotation in the wrong direction), but the matrix seems valid, for example it produces the same result as hgtransform:

>> M

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

>> pos = [1,0,0,0]

pos =

1.0000e+000 0.0000e+000 0.0000e+000 0.0000e+000

>> pos * M

ans =

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

>> Mhgt = makehgtform('translate', [0.5 0.5 0], 'zrotate', -pi/6)

Mhgt =

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

>> pos * Mhgt

ans =

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

Answer by Walter Roberson
on 22 Feb 2017

You appear to have the wrong sign on one of your coefficients.

M = makehgtform('translate', [0.5 0.5 0], 'zrotate', -pi/6)

or +pi/6 when you figure out which you want.

Richard Crozier
on 22 Feb 2017

Richard Crozier
on 22 Feb 2017

Richard Crozier
on 22 Feb 2017

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## Richard Crozier (view profile)

## Direct link to this comment

https://ch.mathworks.com/matlabcentral/answers/326343-why-is-my-matlab-hgtransform-matrix-invalid#comment_430919

Sign in to comment.