Search code examples
rrgl

rgl Problems: surface3d problem when plotting squares


I want to visualize a square with rgl have problems with my code. First 4 surface3d code chunks are working, but the last two aren't. It is exactly the same type of code and I don´t understand the reason why rgl cannot plot it.

See my code below:

open3d()

A<-c(0,1)
B<-c(0,2)
C<-c(0,1)

x_3D<-c(min(A),max(A))
y_3D<-c(min(B),max(B))
z_3D<-matrix(c(max(C)),nrow = 2,ncol = 2)
surface3d(x=x_3D, y=y_3D, z=z_3D)

x_3D<-c(min(A),max(A))
y_3D<-c(min(B),max(B))
z_3D<-matrix(c(min(C)),nrow = 2,ncol = 2)
surface3d(x=x_3D, y=y_3D, z=z_3D)

x_3D<-c(min(A),min(A))
y_3D<-c(min(B),max(B))
z_3D<-matrix(c(min(C),max(C)),nrow = 2,ncol = 2)
surface3d(x=x_3D, y=y_3D, z=z_3D)

x_3D<-c(max(A),max(A))
y_3D<-c(min(B),max(B))
z_3D<-matrix(c(min(C),max(C)),nrow = 2,ncol = 2)
surface3d(x=x_3D, y=y_3D, z=z_3D)

##last surfaces are not ploted but also no error

x_3D<-c(min(A),max(A))
y_3D<-c(min(B),min(B))
z_3D<-matrix(c(min(C),max(C)),nrow = 2,ncol = 2)
surface3d(x=x_3D, y=y_3D, z=z_3D)

x_3D<-c(min(A),max(A))
y_3D<-c(max(B),max(B))
z_3D<-matrix(c(min(C),max(C)),nrow = 2,ncol = 2)
surface3d(x=x_3D, y=y_3D, z=z_3D)

Can someone see my mistake?

EDIT: edited the c&p mistake, but still not rendering the last two surfaces.


Solution

  • You seem to be misunderstanding how the surface3d() function works. When x and y are vectors (as in your data), it attaches the x values to each row of the z matrix, and the y values to each column.

    In your third example, where x_3D is constant, this is fine, because you have two different z_3D values for each y_3D value. But in the last two examples, each x_3D value gets the same z_3D value, so the "surface" is degenerate.

    You can see this by adding row and column names to the z_3D matrix. For example, with the last one:

    A<-c(0,1)
    B<-c(0,2)
    C<-c(0,1)
    
    x_3D<-c(min(A),max(A))
    y_3D<-c(max(B),max(B))
    z_3D<-matrix(c(min(C),max(C)),nrow = 2,ncol = 2)
    
    rownames(z_3D) <- paste("x=", x_3D)
    colnames(z_3D) <- paste("y=", y_3D)
    z_3D
    #>      y= 2 y= 2
    #> x= 0    0    0
    #> x= 1    1    1
    

    Created on 2022-08-15 by the reprex package (v2.0.1)

    This will plot a single cell on the surface, with each of the vertices (0, 2, 0) and (1, 2, 1) repeated twice. That is infinitely thin, so it is invisible.

    On the other hand, the same calculation with your third example gives

    A<-c(0,1)
    B<-c(0,2)
    C<-c(0,1)
    
    x_3D<-c(min(A),min(A))
    y_3D<-c(min(B),max(B))
    z_3D<-matrix(c(min(C),max(C)),nrow = 2,ncol = 2)
    
    rownames(z_3D) <- paste("x=", x_3D)
    colnames(z_3D) <- paste("y=", y_3D)
    z_3D
    #>      y= 0 y= 2
    #> x= 0    0    0
    #> x= 0    1    1
    

    Created on 2022-08-15 by the reprex package (v2.0.1)

    The cell now has 4 different points: (0, 0, 0), (0, 2, 0), (0, 0, 1) and (0, 2, 1), so it is not degenerate, and you can see it.

    By the way, it would probably make more sense to use quads3d to print single quadrilaterals rather than using surface3d; then this would have been obvious. And if you just want a rectangular prism, transforming cube3d() is a quick way to get it.