R rgl text3d() 工件块对象并更改绘图范围

Posted

技术标签:

【中文标题】R rgl text3d() 工件块对象并更改绘图范围【英文标题】:R rgl text3d() artifacts block objects and change plot extent 【发布时间】:2018-12-14 06:16:01 【问题描述】: R 3.5.1 RStudio 1.1.463 rgl 0.99.16 额外字体 0.17 Windows 10 内部版本 1809

当我用quads3d() 绘制一个形状,然后添加一个text3d() 对象时,我发现了3 个问题(我认为它们是相关的,因此这里只有一个帖子):

    text3d() 对象会产生干扰 绘画;它们看起来像与文本相交的文本后面的表面 以奇怪的方式绘制物体。 绘图缩小(并且范围/bbox 更改) - 我可以使用 ignoreExtent=T 使其不缩放,但如果我这样做 axes3d(),bbox 会比没有文本的那个大得多.这似乎表明插入了相当大的几何图形。几个字符的文字尺寸这么大怎么办? 文字看起来很糟糕;像素化、数学符号弱等。

我尝试了不同的字体系列(包括基本的四种)、颜色和其他文本参数。我使用了 extrafont 包并使用 font_import() 加载了我的 Windows 字体。如果它是一个新的 R 会话/环境并不重要。它发生在 plotMath=T 或 F 时。

我正在使用的几何体很小,大致适合一个单位立方体,这有什么不同吗?

我怎样才能摆脱伪影并获得不改变情节尺寸的美观文本?谢谢。

下面是示例代码:

# Draw a 3D Shape and Label it

library(rgl)
library(extrafont)

# Open a new device in which to display the diagram
open3d(windowRect=c(900,200,1700,800))

# Define vertices of the faces

A0 <- c(0, 0.1, -0.02)
B0 <- c(0, -0.1, -0.02)
C0 <- c(0, -0.1, 0.02)
D0 <- c(0, 0.1, 0.02)

Al <- c(1, 0.02, -0.1)
Bl <- c(1, -0.02, -0.1)
Cl <- c(1, -0.02, 0.1)
Dl <- c(1, 0.02, 0.1)

# Define the quadrangles to be visualized

Face0 <- c(A0, B0, C0, D0)
Facel <- c(Bl, Al, Dl, Cl)

Side1 <- c(A0, Al, Bl, B0)
Side2 <- c(B0, Bl, Cl, C0)
Side3 <- c(C0, Cl, Dl, D0)
Side4 <- c(D0, Dl, Al, A0)

# Draw faces and sides
TColor <- "steelblue"
TAlpha <- .25
F0 <- quads3d(matrix((Face0), nrow=4, byrow=T), col=TColor, alpha=TAlpha)
Fl <- quads3d(matrix((Facel), nrow=4, byrow=T), col=TColor, alpha=TAlpha)
S1 <- quads3d(matrix((Side1), nrow=4, byrow=T), col=TColor, alpha=TAlpha)
S2 <- quads3d(matrix((Side2), nrow=4, byrow=T), col=TColor, alpha=TAlpha)
S3 <- quads3d(matrix((Side3), nrow=4, byrow=T), col=TColor, alpha=TAlpha)
S4 <- quads3d(matrix((Side4), nrow=4, byrow=T), col=TColor, alpha=TAlpha)

运行这么多会产生漂亮的 3d 形状图像:

如果我运行以下代码来添加文本标签,

# Label a point

Cx <- c(.6,-0.052,0.068)

Xcolor <- "#000000"

points3d(Cx[1], Cx[2], Cx[3], col=Xcolor, size=5)
points3d(matrix(Cx, nrow=1), col=Xcolor, size=5)

XVertexColor <- "darkseagreen4"
par3d(ignoreExtent=F)

labelCx <- text3d(x=Cx[1], y=Cx[2], z=Cx[3], adj=c(0,0), family="Calibri", cex=1, font=2, text=expression(bold(sqrt(1/C[3](x)))), usePlotmath=T, col=XVertexColor)

...看起来像这样(使用 ignoreExtent=F): The same rgl device, the only change has been the point and the text3d() 缩放和旋转图像会显示干扰几何体视图的文本伪影:

请注意,平方根符号几乎不可见;无论是什么字体系列,无论是否应用bold(),都是如此。

【问题讨论】:

由于您是新的贡献者,我建议您将我的答案在下面标记为“已接受”,或者在其上发表评论以解释缺少的内容。这就是 *** 最终得到一系列好答案的方式。 非常感谢!都非常有用! 【参考方案1】:

rgl 绘制透明(即alpha &lt; 1)对象的方式的一个已知限制是它们并不总是很好地交互。问题是透明物体需要在当前视图中按从远到近的顺序绘制,但是如果你有两个相交的透明多边形,有些部分需要按一个顺序绘制,有些部分需要在相反的顺序。由于rgl 没有将它们分割成单独的部分,因此某些部分会被错误地绘制。

这会影响文本,因为文本被绘制为四边形,背景使用alpha = 0 绘制,文本使用alpha = 1 绘制。如果包含文本的四边形与透明多边形相交,则其中一个的某些部分将绘制得很差。

您可以通过增加initCex 参数来减少文本的像素化;请参阅?plotmath3d 进行讨论。不幸的是,这使得平方根符号看起来更糟:我认为无论大小如何,它都是以恒定宽度绘制的(通过基本图形函数,而不是rgl)。您可以使用

在基本图形中看到这一点
plot(1,1, type="n")
text(1,1,expression(bold(sqrt(1/C[3](x)))), cex = 5)

使用较小的initCex 会产生更好的平方根比例,但会变得模糊或像素化(取决于大小)。 (注意:请参阅下面的补充内容。)

编辑添加:

关于边界框的变化:这绝对看起来像一个错误,但它似乎又是设计的一个限制。如前所述,文本是在透明四边形上绘制的。这个四边形由sprites3d 绘制,这意味着它不随场景旋转,它始终面向观察者。如果您有ignoreExtent = FALSE,那么rgl 会尝试确保四边形适合场景,无论方向如何,即它占用与四边形周围的球体相同的空间。

您的场景在 X 方向上比在 Y 或 Z 方向上大得多,因此球体确实会扭曲事物。

这里的解决方案是使用ignoreExtent = TRUE 以便边界框忽略那个球体。记得之后恢复它。

另一个改进是可能的。由于您不想要可调整大小的文本,您可以通过将cexinitCex 设置为相同的值,但使用不同的材料属性进行绘制来改进它的绘制方式。前 添加文本,将texminfiltertexmagfilter 都设置为"nearest",事情看起来有点像素化,但比你看到的要好。

将两个更改放在一起:

也就是说,将最后两行代码更改为:

saveIgnore <- par3d(ignoreExtent = TRUE)
saveFilter <- material3d(texminfilter = "nearest", texmagfilter = "nearest")
labelCx <- text3d(x=Cx[1], y=Cx[2], z=Cx[3], adj=c(0,0),
                  family="Calibri", cex = 1, initCex = 1, font=2,
                  text=expression(bold(sqrt(1/C[3](x)))), 
                  usePlotmath=TRUE, col=XVertexColor)
material3d(saveFilter)
par3d(saveIgnore)

第二次编辑:

对于您的第一个问题,有一些解决方法。最简单的是将文本从任何透明的地方移开,或者使透明的东西不透明。但是如果你真的想在透明对象附近放置文本,设置材质属性depth_mask = FALSE 将意味着文本的四边形将永远不会遮挡它后面的任何东西。这可能是一个很好的默认值。设置depth_test = "always" 意味着没有任何东西可以掩盖文本。这可能会导致看起来相当奇怪的显示,所以我一般不会推荐它,但你的 alpha = 0.25 表面看起来并不算太糟糕。

【讨论】:

以上是关于R rgl text3d() 工件块对象并更改绘图范围的主要内容,如果未能解决你的问题,请参考以下文章

如何在R / Shiny中将相机方向固定在交互式3D绘图中

R:rgl 包的 writePLY 函数未正确写入顶点颜色

如何使用 RGL 中的 tmesh3d 在 RGL 中使用 shade3d 或 wire3d 制作 3D 网格

R:将rgl小部件组合并保存为单个html文件

更改R中另一个绘图中单击的绘图限制

R语言使用rgl包的plot3d函数可视化可以交互旋转的3D散点图(Rotating 3D scatter plot produced by the plot3d functio in rgl)