Search code examples
r3drgl

Making a 3D cylinder out of a polygon


I have a polygon which I would like to convert to a cylindrical 3D object for an illustration:

x <- structure(list(x = c(7.99, 6.25, -1.77, -1.8, -0.48, 3.93, 7.99
), y = c(2.84, 2.31, 2.43, 2.98, 3.19, 3.26, 2.84)), row.names = c(NA, 
7L), class = "data.frame")

plot(x$x, x$y, type = "n")
polygon(x$x, x$y, col = "blue")
points(x$x, x$y)

enter image description here

I cannot get my head around how to add z-axis with values 2 and 5 for example:

library(rgl)
lines3d(x = rep(x$x, 2), y = rep(x$y, 2), z = rep(c(2, 5), each = nrow(x)))

enter image description here

I would like to make the faces colored and connected. Something like the cylinders on Wikipedia illustrations, but naturally not round ends, but those polygons instead. tringles3d or polygon3d functions are probably what I should use if I used the rgl package, but I don't understand how to restructure my data.frame. I do not need to do this in rgl. That was just the R package which seemed most feasible for this task. How should I reorganize my data to plot the 3D cylinder?


Solution

  • You need to use extrude3d to create an "extrusion" of your polygon. For example, with x as defined in the question,

    x[-1,] %>% 
      extrude3d(thickness = 3, material = list(col = rainbow(14)),
                meshColor = "faces") %>%
      translate3d(x = 0, y = 0, z = 2) %>%
      shade3d()
    

    produces this image (after some manual rotation):

    screenshot

    It uses x[-1,], because you repeated the first vertex at the end: it wants unique vertices.

    The coloring is kind of funny: to draw the hexagons on each end, rgl draws 4 triangles, and each is treated as a separate face for the purpose of coloring. If you want solid colors there, remember that the ends are drawn first: so use something like

    material = list(col = rainbow(8)[c(1,1,1,1,2,2,2,2:8)])
    

    instead.

    The other funny argument to extrude3d is thickness: the polyhedron is drawn between z=0 and z=thickness. Since you wanted z from 2 to 5, the thickness is 3, and the result needs to be translated up 2 units in z.

    There's also cylinder3d, which is used for generating tubular structures, but extrude3d is simpler to use if you only want your polygon to show up in two places at right angles to the sides.