3
votes

I have 3D points and I need to make an 2D orthographic projection of them onto a plane that is defined by the origin and a normal n. The meaning of this is basically looking at the points from the top (given the vertical vector). How can I do it?

What I'm thinking is:

  1. project point P onto the 3D plane: P - P dot n * n
  2. look at the 3D plane from the "back" in respect to the normal (not sure how to define this)
  3. do an ortho projection using max-min coordinates of the points in the plane to define the clipping

I am working with iOS.

1
The P - P dot n * n should be sufficient for projecting the points onto the plane. Maybe I'm missing something? - eigenchris
@eigenchris I need to have the 2D coordinate system lying on that plane so that I can compare x and y coordinates of points - aledalgrande
I understand. I'll write up an answer. - eigenchris

1 Answers

0
votes

One way to do this would be to:

  1. rotate the coordinate system so that the plane of interest lies in the x-y plane, and the normal vector n is aligned with the z-axis
  2. project the points onto the x-y plane by setting their z-components to 0

Set up the coordinate transformation

There are infinitely many solutions to this problem since we can always rotate a solution in the x-y plane to get another valid solution.

To fix this, let's choose a vector v lying in the plane that will line up with the x-axis after the transformation. Any vector will do; let's take the vector in the plane with coordinates x=1 and y=0.

Since our plane intersects the origin, its equation is:

x*n1 + y*n2 + z*n3 = 0
z = -(x*n1 + y*n2)/n3

After substituting x=1, y=0, we see that

v = [1 0 -n1/n3]

We also need to make sure v is normalized, so set

v = v/sqrt(v1*v1 + v2*v2 + v3*v3)

EDIT: The above method will fail in cases where n3=0. An alternative method to find v is to take a random point P1 from our point set that is not a scalar multiple of n and calculate v = P1 - P1 dot n * n, which is the projection of P1 into the plane. Just keep searching through your points until you find one that satisfies (P1 dot n/norm(n)) != P1 and this is guaranteed to work.

Now we need a vector u that will line up with the y-axis after the transformation. We get this from the cross product of n and v:

u = n cross v

If n and v are normalized, then u is automatically normalized.

Next, create the matrix

M = [ v1 v2 v3 ]
    [ u1 u2 u3 ]
    [ n1 n2 n3 ]

Transform the points

Now given a 3 by N array of points P, we just follow the two steps above

  1. P_transformed = M*P
  2. P_plane = set the third row of P_transformed to zero

The x-y coordinates of P_plane are now a 2D coordinate system in the plane.

If you need to get the 3D spatial coordinates back, just do the reverse transformation with P_space = M_transpose*P_plane.