## rgl: drawing a cube with colored faces, vertex points and lines

To demonstrate the effect of linear transformations in 3D, `x -> A x`

, I want to draw a cube and show its transformation under `A`

. For this, I need to color each face separately, and also show the vertex points and the lines that outline each face.

I can't figure out how to use distinct colors for the faces, and how to make this more general so I don't have to repeat all the steps for the result under the transformation.

what I tried:

```
library(rgl)
c3d <- cube3d(color=rainbow(6), alpha=0.5)
open3d()
shade3d(c3d)
points3d(t(c3d$vb), size=5)
for (i in 1:6)
lines3d(t(c3d$vb)[c3d$ib[,i],])
```

This gives the image below. But I don't understand how the faces are colored. And, I seem to have to use `points3d`

and `lines3d`

on the components of the `c3d`

shape, and don't have a single object I can transform.

A particular transformation is given by the matrix `A`

below, and here is how I add that to the scene,

```
A <- matrix(c( 1, 0, 1, 0, 2, 0, 1, 0, 2), 3, 3)
c3d_trans <- transform3d(c3d, A)
shade3d( c3d_trans )
points3d(t(c3d_trans$vb), size=5)
```

This gives:

Is there some way to simplify this and make it more generally useful?

Show source

## Answers ( 3 )

In

`rgl`

, when drawing primitive shapes, you apply colours to vertices, not faces. The faces are coloured by interpolating the colors at the vertices.However,

`cube3d()`

is not a primitive shape, it's a "mesh". It is drawn as 6 separate quadrilaterals. Each vertex is used 3 times.It's not really documented, but the order the colours are used is that the first 4 are used for one face, then the next 4 for the next face, etc. If you want your colours to be

`rainbow(6)`

, you need to replicate each colour 4 times:I'd recommend a higher

`alpha`

value; I find the transparency a little confusing at`alpha = 0.5`

.By the way, for the same purpose, I generally use a shape that looks more spherical as the baseline; I think it gives better intuition about the transformation. Here's code I have used:

and this gives this shape:

which transforms to this:

Of course, it all looks better if you can rotate it.

The second part of my question-- how to generalize this a bit -- was unanswered. Here is a simple function I'm now using to make the steps reusable.

(Note: I use

`rgl version 0.96.0`

. If my memory is correct,`wire3d()`

and`dot3d()`

rules have been changed)It isn't a good idea to give a color informatin when you make a class

for example;`mesh3d`

object, because`shade3d()`

,`wire3d()`

and`dot3d()`

use it in the different ways. It would be better to give plot-function a color information when you draw a object.[ the details related to colors and mesh3d.obj ]Most important rule is that

a vertex consumes a colorwhenever it is used (but it is a bit complex, please see below exampe). I call below matrixiband`mesh3d.obj$vb`

's col numberindex.shade3d() rule(it's easy)wire3d rule(complex and terrible..; edited)In one

`ib`

's`col`

, one vertex have only one color (e.g., at`ib[,1]`

, Index3's color information is used both 1-3 and 3-4. When the line already has been drawn, it is skipped. It istoo difficult (some patterns is impossible)to draw lines in different colors using`wire3d()`

. If you want to do, it would be better to use`lines3d()`

or`segments3d()`

dot3d ruleif you give

`col=1:8`

, NOT index2 but index3 becomes`col = 2`

(`red`

).So,

`col = c("col1", "col2", ..., "col8")[unique(c(object$ib))]`

means index1 is`col1`

, index2 is`col2`

.