Search code examples
r3dtransparencyrgl

R transparent planes3d should not hide plot3d points/spheres


I want to put points/spheres and a plane in one 3d-plot. I would like the plane to be have an alpha-transparency of ~0.5 (it should neither be completely transparent nor completely opaque). So that I can see the points/spheres and the axis through the plane.

I tried:

library(rgl)

#Generating points:
m=20
a1=runif(m,-1,1)
a2=runif(m,-1,1)
b=a1+2*a2+rnorm(m,mean=0,sd=0.3)

# Plotting the points:
plot3d(a1,a2,b, type='s', xlim = c(-1, 1), ylim = c(-1, 1), zlim = c(-3.1, 3.1),xlab = 'a_i,1', ylab = 'a_i,2', zlab = 'b_i',alpha=0.9)
# Plotting the transparent plane:
planes3d(1, 2, -1, 0, col = 'red', alpha = 0.1, add=T)
# plot the points again (because I thought, maybe the the execution order could be relevant)
plot3d(a1,a2,b, add=T, type='s', xlim = c(-1, 1), ylim = c(-1, 1), zlim = c(-3.1, 3.1),xlab = 'a_i,1', ylab = 'a_i,2', zlab = 'b_i',alpha=0.9)

The result that I get is that I can see the axis through the plane, but I cannot see the points/spheres that hide behind the plane :(

parts of the spheres can't be seen through the plane: enter image description here

I wish to see also the points/spheres through the plane (like it works so well for the axis, that can seen through the plane). I want to see all 20 points / spehres, also those that are covered / hidden / concealed / masked by the plane.


Solution

  • You are using "data oriented routines", which render quickly, but distort the axes since the data points typically do not relate to each other geometrically. Probably it is clipping and rendering for speed and ignoring alpha buffers in order to rapidly be able to plot a lot of points.

    If you use a different rendering technique you can get this, but it is a lot slower of course. And it respects the aspect ratio between the coordinates.

    library(rgl)
    
    sphere3d <- function(cen, r=1,n = 65, ...){
      f <- function(s,t){ 
        cbind(   r * cos(t)*cos(s) + cen[1],
                 r *        sin(s) + cen[2],
                 r * sin(t)*cos(s) + cen[3])
      }
      persp3d(f, slim = c(-pi/2,pi/2), tlim = c(0, 2*pi), n = n, add = T,axes=T,...)
    }
    
    m=20
    xx=runif(m,-1,1)
    yy=runif(m,-1,1)
    zz=xx+2*yy+rnorm(m,mean=0,sd=0.3)
    
    # Plotting the points:
    for (i in 1:m){
      cen <- c(xx[i],yy[i],zz[i])
      sphere3d(cen,col="black",r=0.15,n=17)
    }
    
    # add corner points to make the bounding box span the space
    sphere3d(c(-1,-1,-3),col="black",r=0.15,n=17)
    sphere3d(c( 1, 1, 3),col="black",r=0.15,n=17)
    
    # Plotting the transparent plane:
    planes3d(1, 2, -1, 0, col = 'red', alpha = 0.5)
    
    # no axes by default
    axes3d( edges="bbox",box=T )
    

    Yielding this - however note that it is also not perfect - and screws up in a similar way when you set transparency on the spheres as well. In general you can only do multiple layer transparency completely correctly with something ray tracing related which is terribly slow:

    enter image description here

    Here is another view head-on with alpha set to 0.8.

    enter image description here