The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
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.
The rgl
graphic can be animated by spinning it around an
axis using spin3d()
. This can be played on screen using
play3d()
or saved to a .gif
file using
movie3d()
.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.