Let's say I have a fully defined normal 3D cartesian space. I will call its axis x, y, and z.

Let's say I have a point in this space located at $x_1, y_1, z_1$, and another point located at $x_2, y_2, z_2$. Let's now have a vector between these two points. I will call it $v_x, v_y, v_z = i$. Let's now say this vector $i$ is the new "x axis" of a new 3D space. Point 1 is the origin of this space and let's say point 2 is one unit vector down the $i$ axis in this space.

Now I have a third point, located at $x_3, y_3, z_3$. Assuming they are not no-linear, I will use the first 3 points to define a plane in the new space, let's call it the "$i-j"$ plane, with $j$ being the new axis created by placing the third point down. Given the fact I know the absolute (with respect to the origin in the original xyz space) how can I find the unit vector of the $j$ axis and the $k$ axis assuming I want the $i, j, k$ axes to be all orthogonal to each other like the original normal $x y z$ space? Can this be done uniquely given that I know the original cartesian coordinates of the first 3 points? i, j and k should correspond to x, y, and z.

The motivation is this. I am given a fourth point. This time I do not know its xyz coordinates, but I know its coordinates in the space created by the first 3 points. I am trying to change those coordinates to xyz but I am not sure how to do this.

I tried the following:

$i = <v_x, v_y, v_z>$

And then rotating 90 degrees counterclockwise with a matrix (specifically the ones here: http://mathworld.wolfram.com/RotationMatrix.html equations 5 and 6), but I am not sure if this is really valid as I'm not sure this rotation is really defined if you only have one axis in your space.

Assuming that's valid, my thought process for using the above matrices was this... if you rotate the x axis 90 degrees counterclockwise around the z axis, the x axis is now on the y axis, so the x axis's vector has effectively turned into the y axis's vector. The matrix given at the link for that would be this:

[[0, 1, 0]

[-1, 0, 0]

[0, 0, 1]]

So I do the above matrix dot producted with the column form of $i$ (which is x in my new space) and the result is $j$ (which is y in my new space) I get is something like this:

$j = <v_y, -v_x, v_z>$

And following the same logic (rotating the x axis around the y axis gives you the z axis, so I rotate the i axis vector using the "rotate around y axis matrix" given above). Additionally, the minus sign for $v_x$ in the above vector bothers me. Imagine the ijk axis were exactly the same (as in, in the same location) as the xyz axis. This would mean that i = <1, 0, 0> since it's the same as x's unit vector. But then rotating this to y with the method given above would give j (or y) = <0, -1, 0> which is pointing the wrong way. I am not sure how to resolve this. Am I just imaging the rotations wrong in my head? Is this a simple "missing a sign in your matrix" issue or something deeper?

But again, I'm not sure if this is really valid. Can you rotate around an axis if you don't know where it is? Is it valid to just pretend the j and k axis function the same way as the y and z axis?

Assuming that's all valid (which I kind of doubt), now say my coordinates of the 4th point in the ijk space are $<i_4, j_4, k_4>$. I try to convert this to xyz space with a change of basis matrix in a similar fashion to this question: How to think about the change-of-coordinates matrix $P_{\mathcal{C}\leftarrow\mathcal{B}}$

Since I "know" the unit vectors i, j, and k in terms of the unit vectors of x, y, and z, I can make a change of basis matrix and then just translate it over so the origins of the two spaces co-incide. But I getting answers that I know are way off. I'm not really sure if I'm going about this the right way at all. My overall goal is to find the coordinates of the fourth point in xyz space given its coordinates in the ijk space I am constructing but I"m not sure if I am even constructing it properly. I think the key to my problem is that I am not correctly forming the ijk space, or perhaps not calculating point 4's coordinates in ijk space correctly. What I actually have is the distance between point 1 and 4, the angle between points 1, 2, and 4, and the dihedral angle between the 1/2/3 plane and the 1/2/4 plane. So essentially, I have point 4 in slightly modified spherical coordinates in ijk space, which I then convert relatively easily to cartesians in ijk space. But after that I hit this wall of linear algebra.

I'm trying to make a program to do this for a lot of points at a time and I am not an expert in linear algebra at all, this is for a computational chemistry thing (of course, the points at atoms). I know a bit but nothing beyond an intro course, so I have been learning a lot of these things myself but I am not really sure if my understandings are accurate.

Thanks for reading this wall of text!


This is a bit easier to work out if you break the transformation down into several steps. I’m assuming that the scale factor that comes from taking $P_2-P_1$ as the unit in the “$i$ direction” applies uniformly in all directions. Since both coordinate systems are orthonormal, the transformation from “$xyz$” space to “$ijk$” space can be broken down into a translation followed by a rotation and finally a dilation.

The first and last steps are easy. The translation subtracts $P_1$ from everything and the dilation scales everything by a factor of $1/s=1/\|P_2-P_1\|$. This just leaves the rotation, which as you’ve already figured out involves finding a new orthonormal basis that points in the desired directions. Since you’re working in 3-D, you can use cross products to do this.

The first unit vector $\mathbf u_1$ (what you’re calling $i$) is just $P_2-P_1$ normalized. Next, generate a unit vector perpendicular to the “$i$-$j$” plane by taking the cross product $\mathbf u_1\times(P_3-P_1)$ and normalizing it. Call the result $\mathbf u_3$. Finally, produce a vector in the “$i$-$j$” plane that’s perpendicular to both of these with another cross product: $\mathbf u_3\times\mathbf u_1$. Normalization is unnecessary for this last one since we’re multiplying perpendicular unit vectors so the result is also a unit vector. Note the order of the factors in that last product, which ensures that the resulting basis is right-handed.

Now, form the matrix $U$ with these three vectors as its columns. We need the inverse of this for the transformation we’re building. By construction, $U$ is orthogonal (a rotation, in fact), so its inverse is its transpose $U^T$, the matrix with the vectors $\mathbf u_k$ as its rows.

If we use homogeneous coordinates, we can combine these three steps into a single $4\times4$ matrix: $$\begin{bmatrix}1/s&0&0&0\\0&1/s&0&0\\0&0&1/s&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}—&\mathbf u_1&—&0\\—&\mathbf u_2&—&0\\—&\mathbf u_3&—&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}1&0&0&\mid\\0&1&0&-P_1\\0&0&1&\mid\\0&0&0&1\end{bmatrix}=\begin{bmatrix}—&\mathbf u_1/s&—&-(\mathbf u_1\cdot P_1)/s\\—&\mathbf u_2/s&—&-(\mathbf u_2\cdot P_1)/s\\—&\mathbf u_3/s&—&-(\mathbf u_3\cdot P_1)/s\\0&0&0&1\end{bmatrix}.$$ Applying this matrix to a point $P$ and expanding, we find, after a bit of rearrangement, that each coordinate $p'_k$ of the transformed point $P'$ is given by $$p'_k=\frac1s\mathbf u_k\cdot(P-P_1)={\mathbf u_k\cdot(P-P_1)\over\|P_2-P_1\|}.\tag{1}$$ This looks plausible. Subtracting $P_1$ takes care of the translation, the dot product computes the projection onto $\mathbf u_k$, and the result of that is scaled to the new units.

Of course, what you really want is the mapping back to $xyz$ space, but that’s just the inverse transformation. To find it, you can expand the equations given in (1) in terms of the $xyz$ coordinates of $P$ and solve the resulting system for them, or go back to the matrix representation. Invert each of the component matrices and multiply them together in reverse order. The inverse of the dilation uses the reciprocal of the scale factor; we’ve already seen that the inverse of the rotation is its transpose; and inverting the translation is a matter of flipping signs. The resulting matrix is $$\begin{bmatrix}\mid&\mid&\mid&\mid\\s\mathbf u_1&s\mathbf u_2&s\mathbf u_3&P_1\\\mid&\mid&\mid&\mid\\0&0&0&1\end{bmatrix}.$$ Remember that $s=\|P_2-P_1\|$, so the first column is really $P_2-P_1$.

This solution is unique up to the signs of the transformed coordinates. The vector $\mathbf u_1$ is fixed, but there are two choices of direction for $\mathbf u_2$ and two for $\mathbf u_3$ (although if you want to stick with a right-handed coordinate system, choosing a direction for $\mathbf u_2$ determines the direction of $\mathbf u_3$).

It looks like the place where your construction of the basis went wrong was when you tried to perform a rotation about the axis $\langle v_x,v_y,v_z\rangle$. The formulas on the Mathworld page that you cited only work for rotations around the coordinate axes. For a rotation about an arbitrary axis, you need something like Rodrigues’ rotation formula. It’s not necessary to do something that elaborate in this case, though. As I demonstrated above, the cross product is your friend when trying to produce perpendiculars in 3-D. (Indeed, Rodrigues’ formula makes use of them for that very purpose.)

  • $\begingroup$ Thanks, it seems you are correct. When I started constructing my basis using cross products as you recommended my results started being (I'm pretty sure) correct. When you say " - $u1$ - " etc in your matrices, you mean "$u1_x u1_y u1_z$ right? I am just making sure. $\endgroup$ – iammax Aug 12 '16 at 17:09
  • $\begingroup$ @iammax That’s right. $\endgroup$ – amd Aug 12 '16 at 17:50
  1. In order to create $j$ as a unit vector orthogonal to $i$ and living in the plane generated by your first 3 points, you can apply Gram-Schmidt algorithm on the basis $(p_2-p_1,p_3-p_1)$. Or you can use rotation of 90 degrees around the line orthognal to this plane.

  2. Then $k$ will be for example the cross product (or vector product) of $i$ and $j$.

  • $\begingroup$ No need to use G-S for this in 3-D. Generate a normal to the plane first via $(p2-p1)\times(p3-p1)$, then generate a vector in the plane that’s orthogonal to both this and $i$ via another cross product. Normalize the results to get $k$ and $j$, respectively. Doing it this way also guarantees a right-handed basis without any need for further checking. $\endgroup$ – amd Aug 12 '16 at 9:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.