One way to do this would be to:
- 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
- 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
P_transformed = M*P
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
.
P - P dot n * n
should be sufficient for projecting the points onto the plane. Maybe I'm missing something? - eigenchris