rgl中的上标和下标

时间:2016-09-06 19:33:01

标签: r rgl

我想在rgl图中使用text3d创建包含下标和上标的标签。

open3d(windowRect=c(500,500,1000,1000))
text3d(0, 0, 0, expression(CO[2]))

生成如下图像:

enter image description here

而且,

open3d(windowRect=c(500,500,1000,1000)) 
text3d(0, 0, 0, bquote("CO"[2]))

制作

enter image description here

如何在rgl中获取下标/上标?

1 个答案:

答案 0 :(得分:3)

不是真的。基础图形有一个完整的" plotmath"用于解析这些表达式并将其转换为绘图命令的基础结构。 rgl根本没有使用它。

我不认为plotmath代码在基本图形之外可用,因此唯一的可能性是丑陋的:

  • 将2D图形显示为3D场景中的位图(请参阅?show2d或?sprites3d)。

  • 编写基础图形驱动程序(或搭载现有的驱动程序)以获取plotmath的内容,并在rgl中重做它。这对其他事情很有用,但很难。

编辑添加:

这是第二次尝试使用精灵。它仍然可以调整为更好:

  • 精灵在场景中调整大小,而文字通常不会。 (也许这是一个功能,而不是一个错误。)您可能需要使用cex设置来获得您想要的功能。

  • 由于您需要标签,因此不支持将文字放入边距。看一下mtext3d函数来做到这一点。

  • 它现在支持text中的多个元素。

  • 它现在有一个adj参数,其行为应该像text3d

  • 它还没有多少测试。

无论如何,这是一个开始。如果您考虑改进,请发布它们。

plotmath3d <- function(x, y = NULL, z = NULL,
               text, 
               cex = par("cex"), adj = par("adj"),
               startsize = 480,
               ...) {
  xyz <- xyz.coords(x, y, z)
  n <- length(xyz$x)
  if (is.vector(text))
    text <- rep(text, length.out = n)
  cex <- rep(cex, length.out = n)
  adj <- c(adj, 0.5, 0.5)[1:2]
  save <- par3d(skipRedraw = TRUE)
  on.exit(par3d(save))
  for (i in seq_len(n)) {
    # The first device is to measure it.  
    f <- tempfile(fileext = ".png")
    png(f, bg = "transparent", width = startsize, height = startsize)
    par(mar = c(0, 0, 0, 0), xaxs = "i", xaxt = "n",  
        yaxs = "i", yaxt = "n",
        usr = c(0, 1, 0, 1))
    plot.new()
    if (is.vector(text))
      thistext <- text[i]
    else
      thistext <- text
    w <- strwidth(thistext, cex = 5, ...)*(2*abs(adj[1] - 0.5) + 1)
    h <- strheight(thistext, cex = 5, ...)*(2*abs(adj[2] - 0.5) + 1)
    dev.off()

    # Now make a smaller bitmap and draw it
    expand <- 1.5
    size <- round(expand*startsize*max(w, h))
    png(f, bg = "transparent", width = size, height = size)
    par(mar = c(0, 0, 0, 0), xaxs = "i", xaxt = "n", 
        yaxs = "i", yaxt = "n",
        usr = c(0, 1, 0, 1))
    plot.new()
    text(0.5, 0.5, thistext, adj = adj, cex = 5, ...)
    dev.off()

    with(xyz, sprites3d(x[i], y[i], z[i], texture = f, textype = "rgba", 
            col = "white", lit = FALSE, radius = cex[i]*size/100))
  }
}