Hello,

I have dig a little bit in matrix for screen coordinates manipulation with modelMatrix() and I am sure one may be interresting of understanding how this is working…

First of all the matrix return by modelMatrix() is a 4 x 4 matrix { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

representing the transformation made by call to translate() , scale() or rotate() …

Sx Xy Xz 0

Yx Sy Yz 0

Zx Zy Sz 0

Tx Ty Tz 1

or

Xx Xy Xz 0

Yx Yy Yz 0

Zx Zy Zz 0

Tx Ty Tz 1

where Sx, Sy, Sz are the scale applied to each axes (x,y,z)

and Tx Ty Tz are the scale applied to each axes (x,y,z)

For rotation, it is a bit more complex, the matrix indicate the portion of each X,Y,Z to apply to each axes (x,y,z).

You will note that Sx=Xx , Sy=Yy and Sz=Zz this mean that rotation and scale are sharing the same value, so if you have both a scale and a rotation, you can not separate them looking at the matrix.

So the simple translation matrix is a multiplication (*) by this matrix:

0 0 0 0

0 0 0 0

0 0 1 0

Tx Ty Tz 1

The simple scaling matrix is a multiplication by this one:

0 0 0 0

0 0 0 0

0 0 1 0

Tx Ty Tz 1

And the rotation part is done using multiplication by the rotation matrix, for a rotation on z of angle r :

cos r - sin r 0 0

sin r cos r 0 0

0 0 1 0

0 0 0 1

For an easy use, codea as some quick multiplication by each of those using :

m=m:translate(Tx,Ty,Tz)

m=m:scale(Sx,Sy,Sz)

m=m:rotate(r) (for a rotation on axe z, case for a 2D transformation for example)

To convert a World Wx,Wy,Wz coordinate to Screen coordinate X,Y,Z you just need to multiply the matrix returned by modelMatrix() by the 4 dimentions vector (Wx,Wy,Wz,0)

The formula is :

X=Wx*Sx + Wy*Yx + Wz*Zx + Tx
Y=Wx*Xy + Wy

*Sy + Wz*Zy + Ty

Z=Wx

*Xz + Wy*Yz + Wz*Sz + Tz

It works in 2D, but you just have more 0 in the matrix !

The beauty of Matrix is that you just have to multiply then to merge transformation.

The inverse of a Matrix will do a reverse transformation (only if determinant is non null)

If you want to play a little with it in 2D, here is a sample program :

– matrix

```
-- Use this function to perform your initial setup
function setup()
iparameter("tx",0,100) -- transpose X
iparameter("ty",0,100) -- transpose Y
parameter("sx",0,2,1) -- scale X
parameter("sy",0,2,1) -- scale Y
iparameter("r",0,360) -- rotation around Z
iparameter("mode",0,1,0) -- When 0 show transformation automatic, when 1 show manual calculation
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
-- This sets the line thickness
strokeWidth(5)
-- Do your drawing here
tm=matrix()
tm=tm:translate(tx,ty)
tm=tm:scale(sx,sy)
tm=tm:rotate(r)
if mode==0 then
translate(tx,ty)
scale(sx,sy)
rotate(r)
stroke(255, 221, 0, 255)
line(250,200,400,450)
else
stroke(91, 28, 241, 255)
a=toscreen(tm,vec2(250,200))
b=toscreen(tm,vec2(400,450))
line(a.x,a.y,b.x,b.y)
end
m=modelMatrix()
resetMatrix()
resetStyle()
for i = 1,16 do
text(i.."="..m[i],100,40*i)
text(i.."="..tm[i],200,40*i)
end
end
function toscreen(mat,ve)
x=mat[1]*ve.x+mat[5]*ve.y+mat[13]
y=mat[2]*ve.x+mat[6]*ve.y+mat[14]
return vec2(x,y)
end
```