Projecting 3D points to 2D plane
Solution 1
If you have your target point P with coordinates r_P = (x,y,z)
and a plane with normal n=(nx,ny,nz)
you need to define an origin on the plane, as well as two orthogonal directions for x
and y
. For example if your origin is at r_O = (ox, oy, oz)
and your two coordinate axis in the plane are defined by e_1 = (ex_1,ey_1,ez_1)
, e_2 = (ex_2,ey_2,ez_2)
then orthogonality has that Dot(n,e_1)=0
, Dot(n,e_2)=0
, Dot(e_1,e_2)=0
(vector dot product). Note that all the direction vectors should be normalized (magnitude should be one).
Your target point P must obey the equation:
r_P = r_O + t_1*e_1 + t_2*e_2 + s*n
where t_1
and t_2
are your 2D coordinates along e_1
and e_2
and s
the normal separation (distance) between the plane and the point.
There scalars are found by projections:
s = Dot(n, r_P-r_O)
t_1 = Dot(e_1, r_P-r_O)
t_2 = Dot(e_2, r_P-r_O)
Example with a plane origin r_O = (-1,3,1)
and normal:
n = r_O/|r_O| = (-1/√11, 3/√11, 1/√11)
You have to pick orthogonal directions for the 2D coordinates, for example:
e_1 = (1/√2, 0 ,1/√2)
e_2 = (-3/√22, -2/√22, 3/√22)
such that Dot(n,e_1) = 0
and Dot(n,e_2) = 0
and Dot(e_1, e_2) = 0
.
The 2D coordinates of a point P r_P=(1,7,-3)
are:
t_1 = Dot(e_1, r_P-r_O) = ( 1/√2,0,1/√2)·( (1,7,-3)-(-1,3,1) ) = -√2
t_2 = Dot(e_2, r_P-r_O) = (-3/√22, -2/√22, 3/√22)·( (1,7,-3)-(-1,3,1) ) = -26/√22
and the out of plane separation:
s = Dot(n, r_P-r_O) = 6/√11
Solution 2
Find the projection of A
onto the normal direction. Then subtract that projection from A
. What is left is the projection of A
onto the orthogonal plane.
The projection of A onto the unit normal direction n
is given by:
(A · n) n
If A = (x, y, z)
and the unit normal is given by n = (nx, ny, nz)
, then the projection of A onto n
is
(x*nx + y*ny + z*nz) n
So the projection of A onto the orthogonal plane is
A - (A · n) n
= (x, y, z) - (x*nx + y*ny + z*nz) (nx, ny, nz)
For example, if A = (1,2,3) and n is the unit normal in direction (4,5,6), then
In [12]: A
Out[12]: array([1, 2, 3])
In [17]: d
Out[17]: array([4, 5, 6])
In [20]: n = d/sqrt(4*4 + 5*5 + 6*6) # make n a unit vector
In [13]: n
Out[13]: array([ 0.45584231, 0.56980288, 0.68376346])
So the projection of A onto the orthogonal plane is
In [15]: A - np.dot(A,n)*n
Out[15]: array([-0.66233766, -0.07792208, 0.50649351])
How to find 2D coordinates:
You'll need to define a 2D coordinate system on the orthogonal plane. In other words, you need to define where the x-axis
and y-axis
are. For example, you could define the x-axis
to be the projection of (1,0,0) onto the orthogonal plane (using the computation shown above). This will work except in the degenerate case where (1,0,0) is normal to the plane.
Once you have unit vectors for the x
and y
axis directions, then you could project A
directly onto x
and y
. The magnitude of those vectors are the 2D coordinates.
For example, this is the projection of (1,0,0) onto the plane. We take this to be the x-axis direction:
In [42]: x = np.array([1,0,0])
In [45]: x = x - np.dot(x, n) * n
In [52]: x /= sqrt((x**2).sum()) # make x a unit vector
In [53]: x
Out[53]: array([ 0.89006056, -0.29182313, -0.35018776])
Here we compute the y-axis direction: The y-axis
direction must be perpendicular to both the normal direction n
and to x
. So we could define y
to be the cross product of n
and x
:
In [68]: y = np.cross(n, x)
In [69]: y
Out[69]: array([ -2.77555756e-17, 7.68221280e-01, -6.40184400e-01])
So here are the coordinates for A
in the plane:
In [70]: np.dot(A, x), np.dot(A, y)
Out[70]: (-0.74414898890755965, -0.38411063979868798)
Lighthink
Updated on March 14, 2020Comments
-
Lighthink about 4 years
Let A be a point for which I have the 3D coordinates x, y, z and I want to transform them into 2D coordinates: x, y. The projection shall be orthogonal on a plane defined by a given normal. The trivial case, where the normal is actually one of the axes, it's easy to solve, simply eliminating a coordinate, but how about the other cases, which are more likely to happen?
-
Lighthink about 10 yearsThanks for your answer, but how do I transform them into 2D coordinates now? I mean removing the z coordinate, like projecting it to a screen.
-
John Alexiou about 10 yearsI think you are over complicating things. All you need is dot products to get the projection distances (coordinates).
-
Lighthink about 10 yearsThanks a lot, I think your answer is better than the first. I was thinking of something like that myself but you clarified things for me. One more question: How do I compute e_1 and e_2?
-
John Alexiou about 10 years
-
John Alexiou about 10 yearsAlternatively you can define your directions based of radial and tangential vectors from the 3D origin (projected onto the plane), or by the intersection of the plane with the
XY
orYZ
orZX
planes. -
John Alexiou about 10 yearsThere are infinitely many ways to define orthogonal vectors to the normal vector. This should be decided when the plane is defined, and not when the point is measured.
-
polkovnikov.ph about 8 yearsShouldn't these vectors be orthonormal rather than orthogonal?
-
John Alexiou about 8 yearsHmm, I never mentioned
e_1
ande_n
should be normalized. My bad.