I have been trying to plot a simple set of planes, using the planes3d() function in my rgl window of my shiny app and nothing is getting the planes to show up.
library("shiny")
library("rgl")
# helper method for making edges
make_edge3d <- function(u, v) { return(sort(c(u,v))) }
rad2deg <- function(rad) {(rad * 180) / (pi)}
deg2rad <- function(deg) {(deg * pi) / (180)}
get_direction_vector <- function(theta, phi){
#Helper function that converts theta and phi (in degrees) into a direction vector
theta <- deg2rad(theta)
phi <- deg2rad(phi)
Z <- sin(phi) * cos(theta)
X <- sin(phi) * sin(theta)
Y <- cos(phi)
return( c(X, Y, Z))
}
#This function will plot the inputted simplicial complex
plot_shape3d <- function(verts, edges, ...){
vert_x <- verts[,1]
vert_y <- verts[,2]
vert_z <- verts[,3]
#Draws the Points
for (i in 1:length(vert_x)){
points3d(vert_x[i], vert_y[i], vert_z[i])
}
#Constructs the edges
for(e in edges){
e_vert <- verts$vert_lab %in% e
p1x = verts$vert_x[e_vert][1]
p2x = verts$vert_x[e_vert][2]
p1y = verts$vert_y[e_vert][1]
p2y = verts$vert_y[e_vert][2]
p1z = verts$vert_z[e_vert][1]
p2z = verts$vert_z[e_vert][2]
lines3d(c(p1x, p2x), c(p1y, p2y), c(p1z, p2z))
}
}
#This graphs filtration planes orthogonal to viewpoint vector going through each point
plot_filtration_planes <- function(verts, edges, direction){
for (i in range(1:nrow(verts))){
vert = verts[i,]
a = direction[1]
b = direction[2]
c = direction[3]
d = -vert[1] * a - vert[2] * b - vert[3] * c
planes3d(a,b,c,d)
}
}
#Main function that plots out the persistence diagram of the 3d simplicial complex
plot3d <- function(phi=0, theta=0, graph3d){
#List of vertex coordinates
vert_x <- c(0, 1, 2, 3, 4)
vert_y <- c(2, 0, 2, 0, 2)
vert_z <- c(0, 0, 0, 0, 0)
#Vertex Labels
vert_lab <- c("v1", "v2", "v3", "v4", "v5")
verts <- data.frame(vert_x, vert_y,vert_z, vert_lab, stringsAsFactors = F)
#Makes the edges between vertices
edges <- list(
make_edge3d("v1", "v2"),
make_edge3d("v2", "v3"),
make_edge3d("v3", "v4"),
make_edge3d("v4", "v5")
)
#offset <- -vert_x[i] * direction[1] - vert_y[i] * direction[2] - vert_z[i] * direction[3]
#Opens up the rgl plot
open3d(useNULL = TRUE)
axes3d()
#Plots out the W shape
plot_shape3d(verts, edges)
#Retrieves a direction vector from the camera position to the origin
direction <- get_direction_vector(theta, phi)
#Plots filtration planes
plot_filtration_planes(verts, edges, direction)
highlevel(integer())
rgl.viewpoint(theta, phi - 90, zoom=.4)
rglwidget()
}
ui <- fluidPage(
titlePanel("PD visualizer"),
tabsetPanel(
tabPanel("3D", fluid=TRUE,
sidebarLayout(
sidebarPanel(
sliderInput(inputId="theta", label="Choose a number between 0 and pi for theta",
value = 0, min=0, max=360, step=1, round=-2),
sliderInput(inputId="phi", label="Choose a number between 0 and two pi for phi",
value = 0, min=0, max=180, step=1, round=-2)
),
mainPanel(fluidRow(column(1, offset=0, rglwidgetOutput("ThreePD", width = 400, height = 150))))
)
)
)
)
server <- function(input, output){
output$PD <- renderCachedPlot({
createPlot(input$num, input$diagonals, input$filtlines, input$graphfile)
},
cacheKeyExpr = {paste(toString(input$num),"Diagonals: ", input$diagonals, "filtlines: ", input$filtlines, "file: ", input$graphfile$datapath)}
)
#output$plot1 <- renderPlot({plotPD3D(input$theta, input$phi, input$graphfile3d, input$diagonals3d)})
output$ThreePD <- renderRglwidget({
plot3d(input$phi, input$theta, input$graphfile3d)
}
)
}
shinyApp(ui = ui, server = server)
The issue is occuring with the plot_filtration_planes function. I am attempting to plot 5 planes, one for each vertex, with these planes being orthogonal to the current viewpoint, as defined by phi and theta. The code seems to be fine for calculating the plane equation, however the planes don't appear anywhere in the rgl device when I call them using planes3d(). Any advice would be much appreciated for this!
A plane is infinite.
rgl
calculates visualization cube limits according to the max limits from all non infinite objects in the scene.
If the plane doesn't belong to the max limits cube, you won't see it.
On the contrary, if the scene contains as an example a cube crossed by the plane, the plane appears:
library(rgl)
library(magrittr)
axes3d()
cube3d(color="black", alpha=0.1) %>% scale3d(4,4,4) %>% wire3d
planes3d(1, 0, 0, 3, col='red',alpha=1)
In this example the plane x + 3 = 0
corresponding to the above plane3d
call is displayed.