3D rotations of a plane
Solution 1
If you have, or can easily compute, the normal vector to the plane that your points are currently in, I think the easiest way to do this will be to rotate around the axis common to the two planes. Here's how I'd go about it:
- Let
M
be the vector normal to your current plane, andN
be the vector normal to the plane you want to rotate into. IfM == N
you can stop now and leave the original points unchanged. -
Calculate the rotation angle as
costheta = dot(M,N)/(norm(M)*norm(N))
-
Calculate the rotation axis as
axis = unitcross(M, N)
where
unitcross
is a function that performs the cross product and normalizes it to a unit vector, i.e.unitcross(a, b) = cross(a, b) / norm(cross(a, b))
. As user1318499 pointed out in a comment, this step can cause an error ifM == N
, unless your implementation ofunitcross
returns(0,0,0)
whena == b
. -
Compute the rotation matrix from the axis and angle as
c = costheta s = sqrt(1-c*c) C = 1-c rmat = matrix([ x*x*C+c x*y*C-z*s x*z*C+y*s ], [ y*x*C+z*s y*y*C+c y*z*C-x*s ] [ z*x*C-y*s z*y*C+x*s z*z*C+c ])
where
x
,y
, andz
are the components ofaxis
. This formula is described on Wikipedia. -
For each point, compute its corresponding point on the new plane as
newpoint = dot(rmat, point)
where the function
dot
performs matrix multiplication.
This is not unique, of course; as mentioned in peterk's answer, there are an infinite number of possible rotations you could make that would transform the plane normal to M
into the plane normal to N
. This corresponds to the fact that, after you take the steps described above, you can then rotate the plane around N
, and your points will be in different places while staying in the same plane. (In other words, each rotation you can make that satisfies your conditions corresponds to doing the procedure described above followed by another rotation around N
.) But if you don't care where in the plane your points wind up, I think this rotation around the common axis is the simplest way to just get the points into the plane you want them in.
If you don't have M
, but you do have the coordinates of the points in your starting plane relative to an origin in that plane, you can compute the starting normal vector from two points' positions x1
and x2
as
M = cross(x1, x2)
(you can also use unitcross
here but it doesn't make any difference). If you have the points' coordinates relative to an origin that is not in the plane, you can still do it, but you'll need three points' positions:
M = cross(x3-x1, x3-x2)
Solution 2
A single vector (your normal - N) will not be enough. You will need another two vectors for the other two dimensions. (Imagine that your 3D space could still rotate/spin around the normal vector, and you need another 2 vectors to nail it down). Once you have the normal and another one on the plane, the 3rd one should be easy to find (left- or right-handed depending on your system).
Make sure all three are normalized (length of 1) and put them in a matrix; use that matrix to transform any point in your 3D space (use matrix multiplication). This should give you the new coordinates.
bendervader
Updated on June 05, 2022Comments
-
bendervader almost 2 years
I'm doing something where I have a plane in a coord sys A with a set of points already on it. I also have a normal vector in space N. How can I rotate the points on coord sys A so that the underlying plane will have the same normal direction as N?
Wondering if any one has a good idea on how to do this. Thanks
-
bendervader about 12 yearsWouldn't this align the z-axis only? there will be more Dof's in either x or y
-
bendervader about 12 yearsMakes sense! I will need to figure out a way to get the other vector :S Thanks!
-
andand about 12 years+1 Good answer. The only gripe (to the extent it rises to the level of a gripe, which is questionable) I have is you didn't mention Quaternion Rotation as a possible alternative to steps 4 and 5. They are somewhat more efficient.
-
David Z about 12 years@andand: usually I'm doing this sort of thing analytically, so I'm not completely familiar with quaternions. But if I have time I'll edit that in.
-
padawan almost 10 yearswhere do you use axis?
-
David Z almost 10 years@cagirici the components of
axis
are thex
,y
, andz
that appear in the formula for the rotation matrix. -
padawan almost 10 years@DavidZ one more question: What do I do if I want to shift the plane with respect to the
d
component? -
user1318499 almost 10 yearsThis will have a divide-by-zero if the two planes are parallel. You should test for
norm(cross(a,b))
~= 0 and then just return the input vector (no rotation needed). Depending on the language and performance, you could also allow it to happen then test for +/-infinity in each component ofaxis
. -
David Z almost 9 years@user1318499 presumably that would be part of the implementation of
unitcross
, but let me edit in a note about that. -
David Z almost 9 years@cagirici I think that goes beyond the scope of this answer.