Using a 4D transformation matrix to scale a 3D object around a given point

I have a 3D object – let's call it $B$ – and I want to scale it by a given amount – let's say $M$ – around a particular point (maybe the center, a corner, or maybe an arbitrary point) – let's say $P$ – using a 4×4 transformation matrix. (For example, if I want to double a certain sphere in size about its center, I specify $B$ to be a sphere, $P$ its center and $M$ to be 2).

My question is, what is this generalized 4×4 matrix?

[For reference, I'm writing a program that I need to use this in and can get a bounding box around $B$, the coordinates of the point $P$ and a double $M$.]

I'm pretty sure my matrix has to be something like:

$$\left( \begin{array}{cccc} M_{11} & M_{12} & M_{13} & 0 \\ M_{21} & M_{22} & M_{23} & 0 \\ M_{31} & M_{32} & M_{33} & 0 \\ 0 & 0 & 0 & 1 \end{array} \right)$$

• I suppose what you need is an affinity. Is your program supposed to allow for any linear transformation? Including, for example, mirroring, rotating, translating other than scaling? – Riccardo Orlando Sep 23 '16 at 15:46
• @RiccardoOrlando Currently, I'm just concerned with scaling. We have separate functions for translation and rotation but nothing particularly for scaling (just a B.transform(Transformation_Matrix);, if you will) – derekantrican Sep 23 '16 at 15:50

If you already implemented translation, then you can translate $P$, the center of your scaling, to $\underline{0}$, the center of your reference system. (The origin of the axis).

Then you apply a scaling centered in the origin: a scaling by a factor $k$ is represented by the matrix: $$\left[ \begin{matrix} k & 0 & 0 & 0 \\ 0 & k & 0 & 0 \\ 0 & 0 & k & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right]$$

And then you apply the opposite translation to what you did before, bringing $\underline{0}$ back to $P$.

If you want to use a single matrix transformation, then all you have to do is multiply the appropriate matrixes "by hand":

$$\left[ \begin{matrix} 1 & 0 & 0 & P_1 \\ 0 & 1 & 0 & P_2 \\ 0 & 0 & 1 & P_3 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} k & 0 & 0 & 0 \\ 0 & k & 0 & 0 \\ 0 & 0 & k & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 & -P_1 \\ 0 & 1 & 0 & -P_2 \\ 0 & 0 & 1 & -P_3 \\ 0 & 0 & 0 & 1 \end{matrix} \right] = \left[ \begin{matrix} k & 0 & 0 & (1-k)P_1 \\ 0 & k & 0 & (1-k)P_2 \\ 0 & 0 & k & (1-k)P_3 \\ 0 & 0 & 0 & 1 \end{matrix} \right]$$

• Is there a way that I can modify the matrix so that I don't have to deal with the "move to 0, then move back" issue? – derekantrican Sep 23 '16 at 15:58
• @derekantrican I edited :) – Riccardo Orlando Sep 23 '16 at 16:02
• Note that you can first generate a matrix by composing the appropriate matrixes - that is, multiplying them together. So you could very well have a function that generates a scaling matrix given center and $k$ factor, and does that multiplication. This would allow it to be extended to all kinds of linear transformations. – Riccardo Orlando Sep 23 '16 at 16:07
• @derekantrican Just remember that matrices must be multiplied right to left... If you want to do transformation $A$, then $B$, then $C$, the resulting matrix is $CBA$. Let me know if the code works. – Riccardo Orlando Sep 23 '16 at 16:13
• It does work (just tested it). Had some trouble when the answer read (k - 1)P_3 but once you edited it, the problem was solved :) – derekantrican Sep 23 '16 at 16:15