Search code examples
rplot3d

Draw a vertical wall over a specified $(x,y)$ curve in plot3D in R


I have a set of coordinate pairs (x,y) that characterize a curve (made of linear segments), such as x=c(1,2,3,4,5) and y=c(1,2,3,2,1). I imagine this curve "lies on the ground" (at z=0), and I wish to draw a vertical wall above the curve. My z axis is between 0 and 1, and I want the wall to cover this entire interval, so that the wall divides my 3D box into two parts. Specifically,

  • The first segment of my wall has these four corners: (1,1,0), (1,1,1), (2,2,0), (2,2,1).
  • The next segment has these four corners: (2,2,0), (2,2,1), (3,3,0), (3,3,1).
  • The third segment has these four corners: (3,3,0), (3,3,1), (4,2,0), (4,2,1).
  • The last segment has these four corners: (4,2,0), (4,2,1), (5,1,0), (5,1,1).

To see the line on the ground, use this:

x=c(1,2,3,4,5)
y=c(1,2,3,2,1)
plot(x,y,type="b")

I want a vertical wall above, done in 3D using plot3D in R. How could I do this?

(Using the function surface3d, I can draw a surface over a mesh of (x,y). However, here I do not have a mesh, I have a single curve. Moreover, for every pair of my (x,y) coordinates, z is an entire interval [0,1] instead of just a point.)


Solution

  • I'm not sure using plot3D, but using rgl (which plot3Drgl supports), it's easy.

    Just draw a sequence of triangles or quadrilaterals over it. For example, suppose your line is a semicircle of radius 1, and you want the wall to be 1 unit high:

    library(rgl)
    theta <- seq(0, pi, len=100)
    x <- cos(theta)
    y <- sin(theta)
    
    # Construct the boundary
    
    x1 <- c(x, rev(x))
    y1 <- c(y, rev(y))
    z1 <- c(rep(0, length(x)), rep(1, length(x)))
    xyz <- cbind(x1, y1, z1)
    lines3d(xyz)
    
    # Quads are elements (1, 2, 199, 200), (2, 3, 198, 199), etc
    
    idx <- as.numeric(t(cbind(1:99, 2:100, 199:101, 200:102)))
    quads3d(xyz, indices=idx, col = "red")
    
    # add axes
    
    decorate3d()
    

    enter image description here