You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在Shiny的renderRglwidget场景中用identify3d()捕获地标坐标?

好问题!首先得明确:identify3d()是针对桌面端rgl窗口设计的交互函数,没办法直接在Shiny的renderRglwidget()生成的WebGL场景里使用。不过我们可以利用rgl对Shiny的原生交互支持,实现点击捕获地标坐标的功能,具体方案如下:

解决方案:在Shiny WebGL场景中捕获地标坐标

1. 核心思路

rgl的WebGL组件会向Shiny发送点击事件数据,我们可以通过input$<widgetId>_click获取点击位置的屏幕坐标,再结合selectpoints3d()函数匹配场景中的地标点,最终提取目标点的精确3D坐标。

2. 修改后的完整代码

UI部分

ui <- fluidPage(
  selectInput("mspec3D", "选择3D规格", choices = unique(out2[[6]][,3])), # 适配你现有数据的选项
  rglwidgetOutput('webgl3D', width = "1200px", height = "400px"),
  verbatimTextOutput("captured_coords") # 用于展示捕获的坐标
)

Server部分

server <- function(input, output, session) {
  observeEvent(input$mspec3D, {
    tt1 <- out2[[6]][out2[[6]][,3] == input$mspec3D, ][1]
    tt1 <- as.numeric(tt1)

    tt2 <- out2[[6]][out2[[6]][,3] == input$mspec3D, ][2]
    tt2 <- as.numeric(tt2)

    tt1 <- out2[[1]][[tt1]]
    tt2 <- out2[[1]][[tt2]]

    output$webgl3D <- renderRglwidget ({
      try(rgl.close())
      # 绘制地标点,保留可识别的属性
      points3d(tt1, size=3, col="dimgray", box=FALSE)
      points3d(tt2, size=3, col="dodgerblue", box=FALSE)
      axes3d()
      # 绑定点击事件,将屏幕坐标传递给Shiny
      rglwidget() %>%
        onRender("function(el, x) {
          el.addEventListener('click', function(e) {
            Shiny.setInputValue('webgl3D_click', {x: e.clientX, y: e.clientY});
          });
        }")
    })
  })

  # 捕获点击并提取坐标
  observeEvent(input$webgl3D_click, {
    # 匹配点击位置对应的3D点
    selected_idx <- selectpoints3d(input$webgl3D_click)
    
    if (!is.null(selected_idx)) {
      # 获取选中点的坐标
      all_points <- rgl::rgl.attrib("points", "vertices")
      target_coords <- all_points[selected_idx, ]
      
      # 在界面展示结果
      output$captured_coords <- renderPrint({
        cat("捕获的地标坐标:\n")
        cat(sprintf("X: %.4f\nY: %.4f\nZ: %.4f", target_coords[1], target_coords[2], target_coords[3]))
      })
    }
  })
}

shinyApp(ui, server)

3. 关键细节说明

  • selectpoints3d():根据点击的屏幕坐标,自动匹配场景中距离最近的3D点,返回该点的索引;可通过threshold参数调整点击灵敏度(默认10像素)。
  • rgl.attrib("points", "vertices"):提取场景中所有点的坐标矩阵,通过索引即可拿到目标点的精确3D坐标。
  • 点击事件绑定:通过onRender()给WebGL组件添加监听,将屏幕点击坐标发送到Shiny的输入对象,实现交互联动。

4. 注意事项

  • 确保你的rgl版本≥0.107.14,较新版本对Shiny交互的支持更稳定。
  • 如果场景中有大量重叠点,建议调整点的size或col属性,提升点击识别的准确性。

内容的提问来源于stack exchange,提问作者JJL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:15:38