Points can be described in many bases. A basis generally1 consists of an origin and an orientation.
Consider the basis with origin = Tychonievich’s Office in Rice 208 and orientation = looking out of his door. In that basis, Einstein Bros Bagles is forward 10 meters, down 4 meters, left 2 meters, or (-2, -4, -10) using our usual -z-is-forward convention.
Consider the basis with origin = front entrace to Rice Hall and orientation = looking out of the building. In that basis, Einstein Bros Bagles is backwards 30 meters, left 1 meter. or (-1, 0, 30).
A homogeneous coordinate matrix performs a change of basis.
The matrix that converts Rice208 coordinates to RiceDoor coordinates is
\begin{bmatrix} 0 & 0 & 1 & 9 \\ 0 & 1 & 0 & 4 \\ -1 & 0 & 0 & 28 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}
Scene graphs generally represent one basis (the child basis) in terms of another basis (the parent basis). By describing the position and orientation of a calf in terms of a thigh, any motion of the thigh automatically moves the calf as well.
This adds a complication when we want to compute orientations to meet constraints: the computations need to happen in a single coordinate system.
Consider the constraint left calf points at right ankle
. We know how to compute a points-at rotation matrix, but that requires as input the current and desired directions, and as given those are in different coordinate systems. So first we need to get them into the same coordinate system.
One option goes as follows:
This works fine, but it does have an odd gotcha. The resulting matrix has to be applied in world coordinates because it was computed in world coordinates. Thus, instead of the old left calf-to-world basis change matrix T_{\text{hip}} R_{\text{hip}} T_{\text{thigh.l}} R_{\text{thigh.l}} T_{\text{calf.l}} R_{\text{calf.l}} the constraint means we now have R_{\text{constraint}} [T_{\text{hip}} R_{\text{hip}} T_{\text{thigh.l}} R_{\text{thigh.l}} T_{\text{calf.l}} R_{\text{calf.l}}] But the constraint matrix needs to rotate around the knee as its origin, not the world origin, so we actually have T_{\text{origin to knee.l}} R_{\text{constraint}} T_{\text{knee.l to origin}} [T_{\text{hip}} R_{\text{hip}} T_{\text{thigh.l}} R_{\text{thigh.l}} T_{\text{calf.l}} R_{\text{calf.l}}]
We also don’t have any easy way to represent the constraint in the calf’s coordinate system, which means we’d find it challenging to limit the constraint based on rotation limits on the calf or the like. For these and other reasons, option 2 is generally preferred.
The other option goes as follows:
This process will be cleaner, but requires the inverse of matrices. Fortunately, those are easy to compute:
Thus, the right calf-to-world basis change matrix is T_{\text{hip}} R_{\text{hip}} T_{\text{thigh.r}} R_{\text{thigh.r}} T_{\text{calf.r}} R_{\text{calf.r}} and the left world-to-calf basis change matrix is R_{\text{calf.l}}^{-1} T_{\text{calf.l}}^{-1} R_{\text{thigh.l}}^{-1} T_{\text{thigh.l}}^{-1} R_{\text{hip}}^{-1} T_{\text{hip}}^{-1} which combine to make a right-to-left transformation of R_{\text{calf.l}}^{-1} T_{\text{calf.l}}^{-1} R_{\text{thigh.l}}^{-1} T_{\text{thigh.l}}^{-1} T_{\text{thigh.r}} R_{\text{thigh.r}} T_{\text{calf.r}} R_{\text{calf.r}} (the hip transformations cancel out).
But the constraint matrix needs to rotate around the knee as its origin, which is the origin of the left calf, so we apply it as [T_{\text{hip}} R_{\text{hip}} T_{\text{thigh.l}} R_{\text{thigh.l}} T_{\text{calf.l}} R_{\text{calf.l}}]R_{\text{constraint}}
Because the constraint is in the calf’s coordinate space, we can also limit the constraint based on rotation limits on the calf and so on.
Forward And Backward Reaching Inverse Kinematics is a position-based method. It’s input starting positions are typically each in a different coordinate system, so the first step is to transform them all into the same coordinate system. World coordinates are generally adequate for this task, though any one of the bone’s coordinate systems can be used instead if you so desire.
After FABRIK runs, we have a sequence of positions in a single coordinate system. But we need rotations, not positions.
The option-2-like solution is something like the following:
The option-1-like solution is more complicated to describe, but overall similar: we orient each bone from root to top as if each were a point-at constraint.
Bases can have scaling too, but that is not very common.↩︎