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 < 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
以便边界框忽略那个球体。记得之后恢复它。
另一个改进是可能的。由于您不想要可调整大小的文本,您可以通过将cex
和initCex
设置为相同的值,但使用不同的材料属性进行绘制来改进它的绘制方式。前
添加文本,将texminfilter
和texmagfilter
都设置为"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() 工件块对象并更改绘图范围的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 RGL 中的 tmesh3d 在 RGL 中使用 shade3d 或 wire3d 制作 3D 网格
R语言使用rgl包的plot3d函数可视化可以交互旋转的3D散点图(Rotating 3D scatter plot produced by the plot3d functio in rgl)