<p>I've done some small changes to how I usually construct my view matrix, here is what I've modified:</p>

<pre><code>// put it after N = ...
U = cross(N, Vspec);
U = U / sqrt(dot(U,U)); % normalize
V = cross(U, N);
</code></pre>

<p>Then I also set N vector as -N to R matrix, like this:</p>

<pre><code>R= [U(1),U(2),U(3),0; % U is direction of camera space X axis
    V(1),V(2),V(3),0; % V is direction of camera space Y axis
    -N(1),-N(2),-N(3),0;
    0   ,   0,   0,1];
</code></pre>

<p><a href="https://www.opengl.org/wiki/GluLookAt_code" rel="nofollow noreferrer">as shown e.g. in the code for lookAt matrix for OpenGL</a></p>

<p>Now you can orient your first graph, as if you look through your camera, this will give you a reference of how it should look on the second graph.</p>

<p>Then orient second graph so that you look through -Z axis, Y looks up, and X from left to right. Because your camera view vector is -Z, up is Y and right is X. Once you orient your second graph like this, you'll see that arrow looks identically to the first graph, ray on graph 2 will be drawn as point, because it is directed along -Z (your view direction), and in camera space end and start points will fall on a same pixels (another hint that it is correct).</p>

<p>I've also modified a bit camera pos, view direction and axes (just to make it easier to observe for myself).</p>

<p>Here are the values, that I've used:
    focus = [1.2,0,1.5]; %The point we're looking at
    Cx = 3; Cy = -3; Cz = 3; %Position of camera</p>

<p>And for the axes:
    axis([-5,5,-6,6,-7,7]);</p>

<p><a href="https://i.sstatic.net/izEmQ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/izEmQ.png" alt="Here is what I&#39;ve got"></a></p>

<p>I can send you whole code if you need.</p>

CC BY-SA 3.0
2016-02-18T22:23:28.900Z
Wouldn't `norm` be better at normalizing also you can write `R[U, 0; V, 0; -N, 0; 0, 0, 0, 1]`
joojaa
CC BY-SA 3.0
2016-02-18T22:34:29.107Z
You are right about norm, but sqrt(dot(x,x)), is the same (I do not know octave/matlab very good, so I use math). Regarding matrix - not really, because U, V, N are columns, correct way would be R = [U', 0; V', 0; -N', 0; 0,0,0,1] :-) but I tried to keep original formatting.
alariq
CC BY-SA 3.0
2016-02-18T22:47:25.633Z
Its the same but really ease of reading would make the code much better... As the original code is a totall mess. Which is mostly why there were not many takers. And the fact that its matlab...
joojaa
CC BY-SA 3.0
2016-02-20T18:26:26.127Z
Thanks very much - I know the original code is a mess - please accept my apologies! I've tried to do it using only simple matlab functions because I will be porting it to an FPGA (in VHDL) - and am simply trying to model the maths!
davidhood2
CC BY-SA 3.0
2016-02-18T22:21:47.970Z
2016-02-18T22:21:47.970Z
alariq
<p>I am attempting to model a simple graphics pipeline (i.e. Local->Word->View->Screen->2D spaces).</p>

<p>I've been looking at the algorithm required to transform from world to view-space and using the following transform<a href="https://i.sstatic.net/NKmCc.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/NKmCc.png" alt="enter image description here"></a></p>

<p>Although I have been using U,V,N,C notation rather than Xc,Yc,Zc,e.</p>

<p>And my matrix transformation at first glance, appears correct: When I plot the vectors onto world space, I get a vector from the camera position to the point we're looking at, and two correctly placed new X and Y vectors (see the left hand image below).</p>

<p><a href="https://i.sstatic.net/RavTO.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/RavTO.png" alt="enter image description here"></a></p>

<p>By looking along the line of sight vector (such that it disappears,and the focus &amp; camera points overlap), as in the middle figure, should (I believe?) give an accurate example of what the resultant viewspace transformation should look like, with the green vertical and right-pointing vectors showing the new X &amp; Y vectors.</p>

<p>However - when I actually do the view space transform I don't get the middle figure, instead, the resultant transform seems to be looking at the object from a different position possibly aligned with one of the axes? This is shown in the right hand figure - which is actually looking at the object from a slightly lower perspective </p>

<p>My question is essentially what have I done wrong, or am I misunderstanding both the transform and thus my results?</p>

<p>Thanks very much,</p>

<p>David</p>

<p><strong>UPDATES</strong></p>

<p>After stepping through the code - I discovered that my <a href="https://books.google.co.uk/books/about/3D_Computer_Graphics.html?id=tQJEAQAAIAAJ&amp;redir_esc=y" rel="nofollow noreferrer">source</a> book was having me convert the line-of-sight vector to spherical coords and then they were being converted straight back again to create R (viewspace coordination matrix). I've eliminated this redundancy (and potential source of errors) but it hasn't solved the problem...</p>

<pre><code>clear; clc; close all;
%======Create World Space (hard-coded values for demo) ===========
ws_vtx = [0,2,0,2,1,0.5,1.5,0.5,1.5,0.5,1.5,0.5,1.5;
    0,0,0,0,-2,0,0,2,2,0,0,2,2;
    0,0,2,2,1,0.5,0.5,0.5,0.5,1.5,1.5,1.5,1.5];
ws_fcs = [1,2,4,3,3,1,6,6,6,6,7,7,9,8,8,8,10,10;
    2,4,3,1,4,4,9,8,7,11,9,13,8,12,10,6,11,13;
    5,5,5,5,1,2,7,9,11,10,13,11,13,13,12,10,13,12];
%==================Create view matrix===================
focus = [1.5,0,1.5]; %The point we're looking at
Cx = 3; Cy = -3; Cz = 3; %Position of camera
Vspec = [0;0;1]; %Specified up direction for view space (i.e. camera orientation)
vector = focus - [Cx,Cy,Cz]; %Vector camera to focus point 
p = sqrt(vector(1)^2 + vector(2)^2 + vector(3)^2); %Total magnitude of vector
N = vector'/p;
V = Vspec - cross(cross(Vspec,N),N); %Create new "up" direction
U = cross(N,V); %Create new x-axis
%Create rotational matrix to view space
R= [U(1),U(2),U(3),0; % U is direction of camera space X axis
    V(1),V(2),V(3),0; % V is direction of camera space Y axis
    N(1),N(2),N(3),0;
    0   ,   0,   0,1];
Tr = [1,0,0,-Cx;
      0,1,0,-Cy;
      0,0,1,-Cz;
      0,0,0,  1];
T = R*Tr; %Total view transform = rotation * translation
%============Plot the camera vectors &amp; World Space=================
grid on; hold on; xlabel('x'); ylabel('y'); zlabel('z');
scatter3(Cx,Cy,Cz,'s'); %Plot the camera position
plot3([Cx, Cx+p*N(1)],[Cy, Cy+p*N(2)],[Cz, Cz+p*N(3)],'g'); %Plot camera vectors
plot3([Cx, Cx+V(1)],[Cy, Cy+V(2)],[Cz, Cz+V(3)],'g');
plot3([Cx, Cx+U(1)],[Cy, Cy+U(2)],[Cz, Cz+U(3)],'g');
scatter3(ws_vtx(1,:),ws_vtx(2,:),ws_vtx(3,:)) %Plot all the points
patch('Faces',ws_fcs','Vertices',ws_vtx','Facecolor', 'none');
for i = 1:length(ws_vtx)
    str = sprintf('%d',i);
    text(ws_vtx(1,i),ws_vtx(2,i),ws_vtx(3,i), str,'FontSize',14, 'Color','r');
end
%====================Viewspace Transform===========================
ws_vtx = T*vertcat(ws_vtx,(ones(1,length(ws_vtx)))); %Transform worldspace
ws_vtx = ws_vtx(1:3,:); %Remove homogenous column
position = T*[Cx;Cy;Cz;1]; focus = T*horzcat(focus,1)'; %Transform set points
position = position(1:3,:); focus = focus(1:3,:); %Remove homogenous columns
%================Plot new viewspace===============================
figure(); grid on; hold on; xlabel('x'); ylabel('y'); zlabel('z');
scatter3(position(1),position(2),position(3),'s'); %Plot new camera vectors
scatter3([position(1); position(1)+focus(1)],...
    [position(2); position(2)+focus(2)],[position(3); position(3)+focus(3)],'s');
plot3([position(1), focus(1)],[position(2), focus(2)],[position(3), focus(3)],'g');
patch('Faces',ws_fcs','Vertices',ws_vtx','Facecolor', 'none');
</code></pre>

CC BY-SA 3.0
2016-02-12T19:20:25.223Z
The object in the right hand image does appear to be at a similar angle to the middle image. It's just that the axes are not the same. Is it only the axes you are asking about, or does the object itself have a problem?
trichoplax is on Codidact now
CC BY-SA 3.0
2016-02-12T20:36:08.070Z
It's essentially the axes - I would have thought that the axes should be rotated to look like the central figure. Instead, it's slightly off, as in the right figure
davidhood2
<transformations><matrix><matlab><vectors>
Correct view-space transform
davidhood2
# Correct view-space transform

(Asked by: username_0 on 2016-02-12)

I am attempting to model a simple graphics pipeline (i.e. Local->Word->View->Screen->2D spaces).

I've been looking at the algorithm required to transform from world to view-space and using the following transform[![enter image description here](https://i.sstatic.net/NKmCc.png)](https://i.sstatic.net/NKmCc.png)

Although I have been using U,V,N,C notation rather than Xc,Yc,Zc,e.

And my matrix transformation at first glance, appears correct: When I plot the vectors onto world space, I get a vector from the camera position to the point we're looking at, and two correctly placed new X and Y vectors (see the left hand image below).

[![enter image description here](https://i.sstatic.net/RavTO.png)](https://i.sstatic.net/RavTO.png)

By looking along the line of sight vector (such that it disappears,and the focus & camera points overlap), as in the middle figure, should (I believe?) give an accurate example of what the resultant viewspace transformation should look like, with the green vertical and right-pointing vectors showing the new X & Y vectors.

However - when I actually do the view space transform I don't get the middle figure, instead, the resultant transform seems to be looking at the object from a different position possibly aligned with one of the axes? This is shown in the right hand figure - which is actually looking at the object from a slightly lower perspective

My question is essentially what have I done wrong, or am I misunderstanding both the transform and thus my results?

Thanks very much,

David

**UPDATES**

After stepping through the code - I discovered that my [source](https://books.google.co.uk/books/about/3D_Computer_Graphics.html?id=tQJEAQAAIAAJ&redir_esc=y) book was having me convert the line-of-sight vector to spherical coords and then they were being converted straight back again to create R (viewspace coordination matrix). I've eliminated this redundancy (and potential source of errors) but it hasn't solved the problem...

```
clear; clc; close all;
%======Create World Space (hard-coded values for demo) ===========
ws_vtx = [0,2,0,2,1,0.5,1.5,0.5,1.5,0.5,1.5,0.5,1.5;
    0,0,0,0,-2,0,0,2,2,0,0,2,2;
    0,0,2,2,1,0.5,0.5,0.5,0.5,1.5,1.5,1.5,1.5];
ws_fcs = [1,2,4,3,3,1,6,6,6,6,7,7,9,8,8,8,10,10;
    2,4,3,1,4,4,9,8,7,11,9,13,8,12,10,6,11,13;
    5,5,5,5,1,2,7,9,11,10,13,11,13,13,12,10,13,12];
%==================Create view matrix===================
focus = [1.5,0,1.5]; %The point we're looking at
Cx = 3; Cy = -3; Cz = 3; %Position of camera
Vspec = [0;0;1]; %Specified up direction for view space (i.e. camera orientation)
vector = focus - [Cx,Cy,Cz]; %Vector camera to focus point 
p = sqrt(vector(1)^2 + vector(2)^2 + vector(3)^2); %Total magnitude of vector
N = vector'/p;
V = Vspec - cross(cross(Vspec,N),N); %Create new "up" direction
U = cross(N,V); %Create new x-axis
%Create rotational matrix to view space
R= [U(1),U(2),U(3),0; % U is direction of camera space X axis
    V(1),V(2),V(3),0; % V is direction of camera space Y axis
    N(1),N(2),N(3),0;
    0   ,   0,   0,1];
Tr = [1,0,0,-Cx;
      0,1,0,-Cy;
      0,0,1,-Cz;
      0,0,0,  1];
T = R*Tr; %Total view transform = rotation * translation
%============Plot the camera vectors & World Space=================
grid on; hold on; xlabel('x'); ylabel('y'); zlabel('z');
scatter3(Cx,Cy,Cz,'s'); %Plot the camera position
plot3([Cx, Cx+p*N(1)],[Cy, Cy+p*N(2)],[Cz, Cz+p*N(3)],'g'); %Plot camera vectors
plot3([Cx, Cx+V(1)],[Cy, Cy+V(2)],[Cz, Cz+V(3)],'g');
plot3([Cx, Cx+U(1)],[Cy, Cy+U(2)],[Cz, Cz+U(3)],'g');
scatter3(ws_vtx(1,:),ws_vtx(2,:),ws_vtx(3,:)) %Plot all the points
patch('Faces',ws_fcs','Vertices',ws_vtx','Facecolor', 'none');
for i = 1:length(ws_vtx)
    str = sprintf('%d',i);
    text(ws_vtx(1,i),ws_vtx(2,i),ws_vtx(3,i), str,'FontSize',14, 'Color','r');
end
%====================Viewspace Transform===========================
ws_vtx = T*vertcat(ws_vtx,(ones(1,length(ws_vtx)))); %Transform worldspace
ws_vtx = ws_vtx(1:3,:); %Remove homogenous column
position = T*[Cx;Cy;Cz;1]; focus = T*horzcat(focus,1)'; %Transform set points
position = position(1:3,:); focus = focus(1:3,:); %Remove homogenous columns
%================Plot new viewspace===============================
figure(); grid on; hold on; xlabel('x'); ylabel('y'); zlabel('z');
scatter3(position(1),position(2),position(3),'s'); %Plot new camera vectors
scatter3([position(1); position(1)+focus(1)],...
    [position(2); position(2)+focus(2)],[position(3); position(3)+focus(3)],'s');
plot3([position(1), focus(1)],[position(2), focus(2)],[position(3), focus(3)],'g');
patch('Faces',ws_fcs','Vertices',ws_vtx','Facecolor', 'none');

```

**Tags:** transformations, matrix, matlab, vectors

> **Comments:**
> **username_1**: The object in the right hand image does appear to be at a similar angle to the middle image. It's just that the axes are not the same. Is it only the axes you are asking about, or does the object itself have a problem?  
> **username_0**: It's essentially the axes - I would have thought that the axes should be rotated to look like the central figure. Instead, it's slightly off, as in the right figure  

---

## 1 answers

### Answer by username_2 on 2016-02-18. Score: 4

I've done some small changes to how I usually construct my view matrix, here is what I've modified:

```
// put it after N = ...
U = cross(N, Vspec);
U = U / sqrt(dot(U,U)); % normalize
V = cross(U, N);

```

Then I also set N vector as -N to R matrix, like this:

```
R= [U(1),U(2),U(3),0; % U is direction of camera space X axis
    V(1),V(2),V(3),0; % V is direction of camera space Y axis
    -N(1),-N(2),-N(3),0;
    0   ,   0,   0,1];

```

[as shown e.g. in the code for lookAt matrix for OpenGL](https://www.opengl.org/wiki/GluLookAt_code)

Now you can orient your first graph, as if you look through your camera, this will give you a reference of how it should look on the second graph.

Then orient second graph so that you look through -Z axis, Y looks up, and X from left to right. Because your camera view vector is -Z, up is Y and right is X. Once you orient your second graph like this, you'll see that arrow looks identically to the first graph, ray on graph 2 will be drawn as point, because it is directed along -Z (your view direction), and in camera space end and start points will fall on a same pixels (another hint that it is correct).

I've also modified a bit camera pos, view direction and axes (just to make it easier to observe for myself).

Here are the values, that I've used:
focus = [1.2,0,1.5]; %The point we're looking at
Cx = 3; Cy = -3; Cz = 3; %Position of camera

And for the axes:
axis([-5,5,-6,6,-7,7]);

[![Here is what I've got](https://i.sstatic.net/izEmQ.png)](https://i.sstatic.net/izEmQ.png)

I can send you whole code if you need.

> **Comments:**
> **username_3**: Wouldn't `norm` be better at normalizing also you can write `R[U, 0; V, 0; -N, 0; 0, 0, 0, 1]`  
> **username_2**: You are right about norm, but sqrt(dot(x,x)), is the same (I do not know octave/matlab very good, so I use math). Regarding matrix - not really, because U, V, N are columns, correct way would be R = [U', 0; V', 0; -N', 0; 0,0,0,1] :-) but I tried to keep original formatting.  
> **username_3**: Its the same but really ease of reading would make the code much better... As the original code is a totall mess. Which is mostly why there were not many takers. And the fact that its matlab...  
> **username_0**: Thanks very much - I know the original code is a mess - please accept my apologies! I've tried to do it using only simple matlab functions because I will be porting it to an FPGA (in VHDL) - and am simply trying to model the maths!  

---

