**- Undocumented Matlab - https://undocumentedmatlab.com -**

Undocumented view transformation matrix

Posted By Yair Altman On April 15, 2015 | __5 Comments__

Everyone knows Matlab’s * view ^{[1]}* function, right? You know, the function that can set a 3D plot to the proper orientation angles and/or return the current plot’s azimuth/elevation angles. I’ve used it numerous times myself in the past two decades. It’s one of Matlab’s earliest functions, dating back to at least 1984. Still, as often as I’ve used it, it was not until I came across Bruce Elliott’s post on CSSM

First, while * view*‘s 2-output syntax (

`[az,el]=view()`

) is well known and documented, there is also a single-output syntax (`T=view()`

) that is neither. To be exact, this syntax is not mentioned in the official documentation pages, but it ```
>> help view
view 3-D graph viewpoint specification.
view(AZ,EL) and view([AZ,EL]) set the angle of the view from which an
observer sees the current 3-D plot. AZ is the azimuth or horizontal
rotation and EL is the vertical elevation (both in degrees). Azimuth
revolves about the z-axis, with positive values indicating counter-
clockwise rotation of the viewpoint. Positive values of elevation
correspond to moving above the object; negative values move below.
view([X Y Z]) sets the view angle in Cartesian coordinates. The
magnitude of vector X,Y,Z is ignored.
Here are some examples:
AZ = -37.5, EL = 30 is the default 3-D view.
AZ = 0, EL = 90 is directly overhead and the default 2-D view.
AZ = EL = 0 looks directly up the first column of the matrix.
AZ = 180 is behind the matrix.
view(2) sets the default 2-D view, AZ = 0, EL = 90.
view(3) sets the default 3-D view, AZ = -37.5, EL = 30.
[AZ,EL] = view returns the current azimuth and elevation.
T = view returns the current general 4-by-4 transformation matrix.
view(AX,...) uses axes AX instead of the current axes.
See also viewmtx, the axes Properties view, Xform.
Reference page in Help browser
doc view
>> surf(peaks); T=view
T =
0.79335 -0.60876 0 -0.092296
0.30438 0.39668 0.86603 -0.78354
0.5272 0.68706 -0.5 8.3031
0 0 0 1
```

Note that the extra highlighted information is probably a documentation oversight by some MathWorker many years ago, since it was removed from the help section in R2014b and does not appear in the doc pages (not even in R2014a). Perhaps it was documented in the early years but then someone for who-knows-what-reason decided that it shouldn’t be, and then forgot to remove all the loose ends until R2014b. Or maybe it was this way from the very beginning, I don’t know.

In any case, just to be clear on this, the transformation matrix out is still returned by * view* in the latest Matlab release (R2015a), just as it has for the past who-knows-how-many releases.

There are several interesting things to note here:

First, MathWorks have still not done a good job of removing all loose ends. Specifically, the `T=view`

syntax is discussed in the doc page (and help section) of the * viewmtx ^{[3]}* function.

To make things worse (and even more confusing), the usage example shown in that doc page is wrong: it says that

`view(az,el); T=view`

returns the same transformation matrix T as `T=viewmtx(az,el)`

. Close, but not the same:```
>> view(30,60); T=view
T =
0.86603 0.5 0 -0.68301
-0.43301 0.75 0.5 -0.40849
-0.25 0.43301 -0.86603 9.0018
0 0 0 1
>> T2=viewmtx(30,60)
T2 =
0.86603 0.5 0 0
-0.43301 0.75 0.5 0
0.25 -0.43301 0.86603 0
0 0 0 1
```

Tough luck I guess for anyone who relies on * viewmtx*‘s output for complex 3D graphics…

T and T2 appear to be related via a transformation matrix (XT=[1,0,0,0; 0,1,0,0; 0,0,-1,0; 0,0,0,1], we’ll use it again below) that fixes the signs of the first 3 columns, and another translation matrix (camera viewpoint?) that provides the 4th column of T.

Another tidbit that should never have been placed in * view*‘s help section in the first place, is the reference to the axes property

In HG1 (R2014a and earlier), the axes’

A complete usage example for some of these properties can be found in MathWorker Joe Conti’s

```
function [p] = local_Data2PixelTransform(ax,vert)
% Transform vertices from data space to pixel space.
% Get needed transforms
xform = get(ax,'x_RenderTransform');
offset = get(ax,'x_RenderOffset');
scale = get(ax,'x_RenderScale');
% Equivalent: nvert = vert/scale - offset;
nvert(:,1) = vert(:,1)./scale(1) - offset(1);
nvert(:,2) = vert(:,2)./scale(2) - offset(2);
nvert(:,3) = vert(:,3)./scale(3) - offset(3);
% Equivalent xvert = xform*xvert;
w = xform(4,1) * nvert(:,1) + xform(4,2) * nvert(:,2) + xform(4,3) * nvert(:,3) + xform(4,4);
xvert(:,1) = xform(1,1) * nvert(:,1) + xform(1,2) * nvert(:,2) + xform(1,3) * nvert(:,3) + xform(1,4);
xvert(:,2) = xform(2,1) * nvert(:,1) + xform(2,2) * nvert(:,2) + xform(2,3) * nvert(:,3) + xform(2,4);
% w may be 0 for perspective plots
ind = find(w==0);
w(ind) = 1; % avoid divide by zero warning
xvert(ind,:) = 0; % set pixel to 0
p(:,1) = xvert(:,1) ./ w;
p(:,2) = xvert(:,2) ./ w;
```

We could even set these hidden properties directly, as Bruno Luong showed ^{[8]} back in 2009 (the bug he reported in the R2009b prerelease was temporary, it still worked ok in R2014a):

`set(gca,'Xform',eye(4))`

In HG2 (R2014b onward), we no longer have access to the hidden properties above. I’m still not exactly sure how to get all the transformations above, but at least the following can be used to replicate the transformation matrix T:

```
% "standard" way to get the transformation matrix
T = view;
% internal way
XT = [1,0,0,0; 0,1,0,0; 0,0,-1,0; 0,0,0,1];
hCamera = get(gca, 'Camera');
T = XT * GetViewMatrix(hCamera);
```

I’m guessing there are probably similar ways to get the other transformation matrices, but I’ll leave that as an exercise to the reader. Anyone who is up to the task is welcome to leave a comment below. Don’t come asking for my help here – I’m off to solve another puzzle. After all, there’s only a week left before my next blog post is due, so I better get started.

In summary, MathWorks have apparently done some cleanup for the new HG2 in R2014b, but I guess there’s still some work left to do (at least on the documentation). More importantly, much more work is needed to provide simple documented/supported ways of doing 3D transformations without banging our heads at all these hidden corners. Or maybe there already is such a way and I’m simply not aware of it, there’s always that possibility…

Categories: Handle graphics, Hidden property, Medium risk of breaking in future versions, Stock Matlab function, Undocumented feature

5 Comments (Open | Close)

Article printed from Undocumented Matlab: **https://undocumentedmatlab.com**

URL to article: **https://undocumentedmatlab.com/articles/undocumented-view-transformation-matrix**

URLs in this post:

[1] view: **http://www.mathworks.com/help/matlab/ref/view.html**

[2] Bruce Elliott’s post on CSSM: **https://www.mathworks.com/matlabcentral/newsreader/view_thread/340301**

[3] viewmtx: **http://www.mathworks.com/help/matlab/ref/viewmtx.html**

[4] example: **https://groups.google.com/d/msg/comp.soft-sys.matlab/bOSDB_chCkw/res_spSLSicJ**

[5] technical details: **https://lists.gnu.org/archive/html/octave-maintainers/2010-11/msg00087.html**

[6] removed from the File exchange: **http://www.mathworks.com/matlabcentral/fileexchange/1241-select3d-m--select3dtool-m**

[7] but can still be found online: **https://github.com/justingardner/mrTools/blob/master/mrUtilities/ImageProcessing/select3d.m**

[8] showed: **https://www.mathworks.com/matlabcentral/newsreader/view_thread/253563**

[9] Matrix processing performance : **https://undocumentedmatlab.com/articles/matrix-processing-performance**

[10] ishghandle's undocumented input parameter : **https://undocumentedmatlab.com/articles/ishghandle-undocumented-input-parameter**

[11] getundoc – get undocumented object properties : **https://undocumentedmatlab.com/articles/getundoc-get-undocumented-object-properties**

[12] Undocumented plot marker types : **https://undocumentedmatlab.com/articles/undocumented-plot-marker-types**

[13] HG's undocumented parameters interface : **https://undocumentedmatlab.com/articles/hgs-undocumented-parameters-interface**

[14] Undocumented scatter plot behavior : **https://undocumentedmatlab.com/articles/undocumented-scatter-plot-behavior**

Click here to print.

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.

5 Comments To "Undocumented view transformation matrix"

#1 CommentByEricOn April 27, 2015 @ 08:49Hi Yair, I haven’t had enough coffee yet on this Monday morning to follow this post entirely, but is makehgtform/hgtransform helpful?

#2 CommentByYair AltmanOn April 27, 2015 @ 09:29@Eric – these functions are related to the article in the sense that they also deal with a 4×4 affine transformation matrix. They can be used in cases when you know in advance the requested rotation/scaling/translation amounts. My article dealt with the undocumented feature of extracting the current matrix from the axes, and af far as I can tell this is not supported by

andmakehgtform.hgtransform#3 CommentByMichelle HirschOn April 27, 2015 @ 10:14Yair –

Thanks for taking the time to point out these inconsistencies in the behavior and documentation. We will clean up the documentation to make things more consistent. We agree that the current state of the view transformation is a bit of a mess. We are keeping it around for compatibility, and are considering your suggestion that we should provide a documented, reliable, and consistent way to work with view transformation matrices.

#4 CommentByYaroslavOn May 12, 2015 @ 04:34There is another semi-documented feature of the view: you can link the

`View`

property across multiple axes. For example,Now, just press the “Rotate 3D” toolbar button, and have both axes rotating together.

#5 CommentByYair AltmanOn May 12, 2015 @ 05:00cute 🙂