This vignette illustrates how linear transformations can be
represented in 3D using the `rgl`

package. It
is explained more fully in this StackExchange discussion 3D
geometric interpretations of matrix inverse. It also illustrates the
determinant, \(\det(\mathbf{A})\), as
the volume of the transformed cube, and the relationship between \(\mathbf{A}\) and \(\mathbf{A}^{-1}\).

Start with a unit cube, which represents the identity matrix \(\mathbf{I}_{3 \times 3}\) =
`diag(3)`

in 3 dimensions. In `rgl`

this is given
by `cube3d()`

which returns a `"mesh3d"`

object
containing the vertices from -1 to 1 on each axis. I translate and scale
this to make each vertex go from 0 to 1. These are represented in
homogeneous coordinates to handle perspective and transformations. See
`help("identityMatrix")`

for details.

```
library(rgl)
library(matlib)
# cube, with each face colored differently
colors <- rep(2:7, each=4)
c3d <- cube3d()
# make it a unit cube at the origin
c3d <- scale3d(translate3d(c3d, 1, 1, 1),
.5, .5, .5)
str(c3d)
## List of 6
## $ vb : num [1:4, 1:8] 0 0 0 1 1 0 0 1 0 1 ...
## $ material : list()
## $ normals : NULL
## $ texcoords: NULL
## $ meshColor: chr "vertices"
## $ ib : num [1:4, 1:6] 1 3 4 2 3 7 8 4 2 4 ...
## - attr(*, "class")= chr [1:2] "mesh3d" "shape3d"
```

The vertices are the 8 columns of the `vb`

component of
the object.

```
c3d$vb
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] 0 1 0 1 0 1 0 1
## [2,] 0 0 1 1 0 0 1 1
## [3,] 0 0 0 0 1 1 1 1
## [4,] 1 1 1 1 1 1 1 1
```

I want to show the transformation of \(\mathbf{I}\) by a matrix \(\mathbf{A}\) as the corresponding transformation of the cube.

```
# matrix A:
A <- matrix(c( 1, 0, 1,
0, 2, 0,
1, 0, 2), 3, 3) |> print()
## [,1] [,2] [,3]
## [1,] 1 0 1
## [2,] 0 2 0
## [3,] 1 0 2
det(A)
## [1] 2
# A can be produced by elementary row operations on the identity matrix
I <- diag( 3 )
AA <- I |>
rowadd(3, 1, 1) |> # add 1 x row 3 to row 1
rowadd(1, 3, 1) |> # add 1 x row 1 to row 3
rowmult(2, 2) # multiply row 2 by 2
all(AA==A)
## [1] TRUE
```

I want to be able to display 3D mesh objects, with colored points,
lines and faces. This is a little tricky, because in rgl colors are
applied to vertices, not faces. The faces are colored by interpolating
the colors at the vertices. See the StackOverflow discussion drawing
a cube with colored faces, vertex points and lines. The function
`draw3d()`

handles this for `"mesh3d"`

objects.
Another function, `vlabels()`

allows for labeling
vertices.

```
# draw a mesh3d object with vertex points and lines
draw3d <- function(object, col=rep(rainbow(6), each=4),
alpha=0.6,
vertices=TRUE,
lines=TRUE,
reverse = FALSE,
...) {
if(reverse) col <- rev(col)
shade3d(object, col=col, alpha=alpha, ...)
vert <- t(object$vb)
indices <- object$ib
if (vertices) points3d(vert, size=5)
if (lines) {
for (i in 1:ncol(indices))
lines3d(vert[indices[,i],])
}
}
# label vertex points
vlabels <- function(object, vertices, labels=vertices, ...) {
text3d( t(object$vb[1:3, vertices] * 1.05), texts=labels, ...)
}
```

We can show the cube representing the identity matrix \(\mathbf{I}\) using `draw3d()`

.
Transforming this by \(\mathbf{A}\) is
accomplished using `transform3d()`

.

The inverse of `A`

is found using `solve()

The determinant of the matrix `A`

here is 2. The
determinant of \(\mathbf{A}^{-1}\) is
the reciprocal, \(1/
\det(\mathbf{A})\). Geometrically, this means that the larger
\(\mathbf{A}^{-1}\) is the smaller is
\(\mathbf{A}^{-1}\).

You can see the relation between them by graphing both together in the same plot. It is clear that \(\mathbf{A}^{-1}\) is small in the directions \(\mathbf{A}\) is large, and vice versa.