3D rotations of a plane

bendervader picture bendervader · Feb 24, 2012 · Viewed 15k times · Source

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

Answer

David Z picture David Z · Feb 24, 2012

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)