[Math] How to calculate transformation matrix from one plane to another

linear-transformationsmatricesmatrix equationstransformationvectors

Let's consider the basic 3D coordinate system. I have a plane P defined with three points A(xa,ya,za), B(xb,yb,zb) and C(xc,yc,zc).
I have some object (a mesh – set of vertices and triangles) in the coordinate system and the plane P is actually a cutting plane, which should split the mesh in two slices.

I will need to transform the mesh (to rotate it) relative to a fixed cutting plane (for example, plane z = 0 is the best fit – I need all values for z value to be equal, in order to do the cutting).

So as a first step in my algorithm, what I will need to do, is to transform (with transformation matrix R) the plane P to the plane z = 0, to use this plane as a reference for cutting the mesh and then to apply the reverse transformation matrix R' so that the mesh slices are transformed backed at their original locations.

My question now is: is it possible to calculate the transformation matrices R and R', based on the three points A, B, C on the plane P?

My guess is that I can do the following (calculate the normal vector by using the points A, B, C):

diffVectorBA = B - A = (xb-xa, yb-ya, zb-za);
diffVectorCA = C - A = (xc-xa, yc-ya, zc-za);
vectorNormal = crossProduct(diffVectorBA, diffVectorCA)
             = (diffVectorBA.Y * diffVectorCA.Z - diffVectorBA.Z * diffVectorCA.Y,
                diffVectorBA.Z * diffVectorCA.X - diffVectorBA.X * diffVectorCA.Z,
                diffVectorBA.X * diffVectorCA.Y - diffVectorBA.Y * diffVectorCA.X);

but after calculating this, I'm not sure how to proceed and how to calculate R and R'?

Best Answer

Constructing an appropriate rotation for this application is easy if you remember two things: the columns of a transformation matrix are the images of the basis vectors, and the inverse of a rotation matrix is its transpose (which you’ve already used in the question.) If you have a right-handed orthonormal basis $(\mathbf u,\mathbf v,\mathbf w)$ of $\mathbb R^3$, then the matrix $R=\begin{bmatrix}\mathbf u&\mathbf v&\mathbf w\end{bmatrix}$ represents a rotation that maps the standard basis vectors onto these. So, if $\mathbf w$ is parallel to the normal of your plane, $R^T$ will rotate it so that it is parallel to the $x$-$y$ plane. You’ll probably want to translate first so that it is mapped onto the $x$-$y$ plane to make the “cut” simpler. You’ve got the plane’s normal $\mathbf n=(B-A)\times(C-A)$. An orthonormal basis that fits the bill is $$\mathbf w = {\mathbf n\over\|\mathbf n\|}, \mathbf u={B-A\over\|B-A\|}, \mathbf v=\mathbf w\times\mathbf u.$$ You can also find a simple way to construct a reflection that maps $\mathbf n$ to the $z$-axis here. The change of orientation is irrelevant since you’re only care about the $z$-coordinates after the transformation, and an advantage of a reflection is that it is its own inverse.

However, transforming your data points in order to do this partitioning is unnecessary. An equation of the partitioning plane is $\mathbf n\cdot(\mathbf x-A)=0$. For points not on the plane, the expression on the left-hand side of this equation is proportional to the signed distance of $\mathbf x$ from the plane. The sign tells you on which side of the plane the point lies: if positive, then it’s on the side toward which $\mathbf n$ points; if negative, it’s on the opposite side from $\mathbf n$. (If zero, the point, of course, lies on the plane.) So, in order to partition your mesh, you need only check the sign of $\mathbf n\cdot\mathbf p-\mathbf n\cdot A$ for each point $\mathbf p$ of your mesh.

Related Question