3D rotations of a plane

17,088

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:

  1. Let M be the vector normal to your current plane, and N be the vector normal to the plane you want to rotate into. If M == N you can stop now and leave the original points unchanged.
  2. Calculate the rotation angle as

    costheta = dot(M,N)/(norm(M)*norm(N))
    
  3. 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 if M == N, unless your implementation of unitcross returns (0,0,0) when a == b.

  4. 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, and z are the components of axis. This formula is described on Wikipedia.

  5. 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.

Share:
17,088
bendervader
Author by

bendervader

Updated on June 05, 2022

Comments

  • bendervader
    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
    bendervader about 12 years
    Wouldn't this align the z-axis only? there will be more Dof's in either x or y
  • bendervader
    bendervader about 12 years
    Makes sense! I will need to figure out a way to get the other vector :S Thanks!
  • andand
    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
    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
    padawan almost 10 years
    where do you use axis?
  • David Z
    David Z almost 10 years
    @cagirici the components of axis are the x, y, and z that appear in the formula for the rotation matrix.
  • padawan
    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
    user1318499 almost 10 years
    This 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 of axis.
  • David Z
    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
    David Z almost 9 years
    @cagirici I think that goes beyond the scope of this answer.