R rgl text3d()工件块对象并更改绘图范围
R rgl text3d() artifacts block objects and change plot extent
- R 3.5.1
- RStudio 1.1.463
- rgl 0.99.16
- extrafont 0.17
- Windows 10 构建 1809
当我用 quads3d()
绘制一个形状然后添加一个 text3d()
对象时,我发现了 3 个问题(我认为它们是相关的,因此这里只有一个 post):
text3d()
对象产生干扰
画画;它们看起来像是与文本相交的文本后面的表面
以奇怪的方式绘制对象。
- 绘图缩小(并且 extent/bbox 更改)- 我可以使用 ignoreExtent=T 使其不缩放,但如果我这样做
axes3d()
,则可以看到 bbox 更大比没有文字的那个。这似乎表明插入了一个相对非常大的几何体。几个字符的文字尺寸这么大怎么办?
- 文字看起来很蹩脚;像素化,数学符号弱等
我尝试了不同的字体系列(包括基本的四种)、颜色和其他文本参数。我使用 extrafont 包并使用 font_import()
加载了我的 Windows 字体。是不是新鲜的Rsession/environment也没关系。它发生在 plotMath=T 或 F.
我正在使用的几何图形很小,大致适合一个单位立方体,这会有什么不同吗?
我怎样才能去除伪影并获得 decent-looking 不改变绘图尺寸的文本?谢谢。
示例代码如下:
# 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()
,都是如此。
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
会尝试确保四边形适合场景而不考虑方向,即它占据与四边形周围的球体相同的 space。
X 方向的场景比 Y 或 Z 方向的场景大得多,因此球体确实会扭曲东西。
此处的解决方案是使用 ignoreExtent = TRUE
以便边界框忽略该球体。记得事后恢复。
另一个改进是可能的。由于您不想要可调整大小的文本,您可以通过将 cex
和 initCex
设置为相同的值,但使用不同的 material 属性来改进它的绘制方式。前
添加文本,将 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)
第二次编辑:
您的第一个问题有一些解决方法。最简单的方法是将文本从任何透明的地方移开,或者使透明的东西不透明。但是如果你真的想让文本靠近透明对象,设置 material 属性 depth_mask = FALSE
将意味着文本的四边形永远不会遮挡它后面的任何东西。这可能是一个很好的默认值。设置 depth_test = "always"
意味着没有任何东西可以遮盖文本。这可能会导致显示效果相当怪异,因此我一般不会推荐它,但对于您的 alpha = 0.25
表面,它看起来并不太糟糕。
- R 3.5.1
- RStudio 1.1.463
- rgl 0.99.16
- extrafont 0.17
- Windows 10 构建 1809
当我用 quads3d()
绘制一个形状然后添加一个 text3d()
对象时,我发现了 3 个问题(我认为它们是相关的,因此这里只有一个 post):
text3d()
对象产生干扰 画画;它们看起来像是与文本相交的文本后面的表面 以奇怪的方式绘制对象。- 绘图缩小(并且 extent/bbox 更改)- 我可以使用 ignoreExtent=T 使其不缩放,但如果我这样做
axes3d()
,则可以看到 bbox 更大比没有文字的那个。这似乎表明插入了一个相对非常大的几何体。几个字符的文字尺寸这么大怎么办? - 文字看起来很蹩脚;像素化,数学符号弱等
我尝试了不同的字体系列(包括基本的四种)、颜色和其他文本参数。我使用 extrafont 包并使用 font_import()
加载了我的 Windows 字体。是不是新鲜的Rsession/environment也没关系。它发生在 plotMath=T 或 F.
我正在使用的几何图形很小,大致适合一个单位立方体,这会有什么不同吗?
我怎样才能去除伪影并获得 decent-looking 不改变绘图尺寸的文本?谢谢。
示例代码如下:
# 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()
,都是如此。
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
会尝试确保四边形适合场景而不考虑方向,即它占据与四边形周围的球体相同的 space。
X 方向的场景比 Y 或 Z 方向的场景大得多,因此球体确实会扭曲东西。
此处的解决方案是使用 ignoreExtent = TRUE
以便边界框忽略该球体。记得事后恢复。
另一个改进是可能的。由于您不想要可调整大小的文本,您可以通过将 cex
和 initCex
设置为相同的值,但使用不同的 material 属性来改进它的绘制方式。前
添加文本,将 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)
第二次编辑:
您的第一个问题有一些解决方法。最简单的方法是将文本从任何透明的地方移开,或者使透明的东西不透明。但是如果你真的想让文本靠近透明对象,设置 material 属性 depth_mask = FALSE
将意味着文本的四边形永远不会遮挡它后面的任何东西。这可能是一个很好的默认值。设置 depth_test = "always"
意味着没有任何东西可以遮盖文本。这可能会导致显示效果相当怪异,因此我一般不会推荐它,但对于您的 alpha = 0.25
表面,它看起来并不太糟糕。