3
votes

Given a point in 3D space, how can I calculate a matrix in homogeneous coordinates which will project that point into the plane z == d, where the origin is the centre of projection.

3
What form of projection do you want? Are you really talking about just (X,Y,Z) => (X,Y,D), a matrix translation of D-Z on the Z axis? Are you trying to find the intersection of the segment between the origin and the point and an offset Z=D plane? Your question needs more details. - Phrogz
Would a matrix specific to that point do, or do you want one constant matrix that will project any point (other than the origin) onto the z=d plane, along the ray from the origin? - Beta
Did you check en.wikipedia.org/wiki/3D_projection ? I think it contains your answer, and explanations on the computation. - Alexandre C.
You're asking form a perspective projection transformation matrix, which is different from perspective transformation matrix. - Pui Ho Lam
I just answered this at length in stackoverflow.com/questions/24163987/… - André Aichert

3 Answers

4
votes

OK, let's try to sort this out, expanding on Emmanuel's answer.

Assuming that your view vector is directly along the Z axis, all dimensions must be scaled by the ratio of the view plane distance d to the original z coordinate. That ratio is trivially d / z, giving:

x' = x * (d / z)
y' = y * (d / z)
z' = z * (d / z)    ( = d)

In homogenous coordinates, it's usual to start with P = [x, y, z, w] where w == 1 and the transformation is done thus:

P' = M * P

The result will have w != 1, and to get the real 3D coordinates we normalise the homogenous vector by dividing the whole thing by its w component.

So, all we need is a matrix that given [x, y, z, 1] gives us [x * d, y * d, z * d, z], i.e.

| x' |  =    | d   0   0   0 |  *  | x |
| y' |  =    | 0   d   0   0 |  *  | y |
| z' |  =    | 0   0   d   0 |  *  | z |
| w' |  =    | 0   0   1   0 |  *  | 1 |

which once normalised (by dividing by w' == z) gives you:

[ x * d / z, y * d / z,   d,   1 ]

per the first set of equations above

1
votes

I guess the projection you mean, as Beta says, consists in the intersection between:

  • the line formed by the origin O(0, 0, 0) and the point P(a, b, c) to be transformed
  • and the plane z=d

If I'm right, then let's have a look at the equation of this line, given by the vectorial product OP ^ OM = 0 (let's remind that the equation of a line between 2 given points A and B is given by AB ^ AM = 0, with M(x, y, z); this is a vectorial product, so all are vectors: 0 represents the null vector, AB is the vector AB, etc):

bz - cy = 0
cx - az = 0
cz - bx = 0

With z = d, we then have only 2 linearily independent equations:

bd = cy
cx = ad

So this projection converts a point P(a, b, c) into a point P'(ad/c, bd/c, d). For homogeneous coordinates that gives:

P'(ad/c, bd/c, d) = P'(ad/c, bd/c, cd/c)
                  = P'(ad/c: bd/c: cd/c: 1)
                  = P'(a: b: c: d/c)

EDIT : the matrix I 1st found was:

    1, 0, 0, 0
    0, 1, 0, 0
A = 0, 0, 1, 0
    0, 0, 0, d/c

but it uses c which is the a coordinate of the point P !! This is nonsense, I couldn't find an expression of A that does not use these coordinates. I may not be familiar enough with homogeneous coordinates.

1
votes

the homogeneous transformation matrix is (Euler roll-pitch-yaw):

|r1 r2 r3 dx|
|r4 r5 r6 dy|
|r7 r8 r9 dz|
|px py pz sf|

r1-9 are the elements of the combined rotation matrix: Rx*Ry*Rz (work it out) dx dy and dz are displacement vector (d) elements px py and pz are the perspective vector (p) elements sf is the scaling factor

from here on, if you use the inverse of this, you get your projection as a perspective in any arbitrary plane by feeding rotations of your target plane, as well as it's position of origin wrt the reference one in (keep perspective vector at 0 0 0 and sf=1 for pure kinematics), you get T->T* = T1. Get T1^-1 (for kinematics, this is simply R' (transposed,), horizontal concatenated by -R'*d, then vertical concatenated simply by 0 0 0 1).

can have multiple planes e.g. a,b,c as a chain, in which case T1 = Ta*Tb*Tc*...

then, v(new) = (T1^-1)*v(old), job done.