英文:
axes change when using overlay with next3d() in rgl
问题
这是问题的一个可重现的示例。我想在rgl中创建共享鼠标的并排plot3d
。
#使用rgl手册中的示例
set.seed(1234)
x <- sort(rnorm(100))
y <- rnorm(100)
z <- rnorm(100) + atan2(x, y)
#创建并排图
open3d()
mfrow3d(1, 2, sharedMouse=TRUE)
plot3d(x, y, z, col=rainbow(100))
arrow3d(c(0, 0, 0), c(2, 2, 2), type="lines")
next3d()
plot3d(x, y, z, col=rainbow(100))
到目前为止一切正常。
现在将arrow3d叠加到右侧的图中
arrow3d(c(0, 0, 0), c(2, 2, 2), type="lines")
坐标轴随着箭头的变化而改变,箭头位置不正确。
我搞不清楚发生了什么。如果我在单独的open3d()
调用中绘制这两个图中的每一个,并使用arrow3d()
,它们看起来是相同的。我尝试了其他方法,比如manipulateWidget包中的combineWidgets
,它可以正常工作,但我无法弄清楚如何在子场景之间共享鼠标。plotly将会很棘手,因为我的应用需要沿着路径创建许多3D箭头以创建轨迹,而且在plotly中实现3D箭头显然不容易,除了在注释之外。
在Mac(x86_64-apple-darwin17.0)上运行R 4.2.2上的rgl 1.1.3。
英文:
Here is a reproducible example of the problem. I want to create side by side plot3d
in rgl with shared mouse.
#use an example from rgl's manual
set.seed(1234)
x <- sort(rnorm(100))
y <- rnorm(100)
z <- rnorm(100) + atan2(x, y)
#create side by side plot
open3d()
mfrow3d(1, 2, sharedMouse=TRUE)
plot3d(x, y, z, col=rainbow(100))
arrow3d(c(0, 0, 0), c(2, 2, 2), type="lines")
next3d()
plot3d(x, y, z, col=rainbow(100))
All good so far.
Now overlay the arrow3d to the plot on the right side
arrow3d(c(0, 0, 0), c(2, 2, 2), type="lines")
and the axes change with the arrow not placed correctly
Can't figure out what is happening. If I plot each of these two plots with arrow3d()
in separate open3d()
calls they look identical. I tried other approaches such as combineWidgets
in the manipulateWidget package, which works correctly but I can't figure out how to share the mouse across subscenes. plotly will be too tricky because my application require many 3d arrows along a path to create a trajectory and 3d arrows apparently are not easy to implement in plotly outside of annotations.
Running rgl 1.1.3 on R 4.2.2 on a mac (x86_64-apple-darwin17.0).
答案1
得分: 1
这是关于rgl.window2user()
函数的一个bug,该函数被arrow3d()
使用。这个问题在rgl
1.1.10版本中已经修复,但只在Github上可用,从源代码安装rgl
并不总是容易的。以下是在CRAN版本1.1.3中仅安装bug修复的一种方法:
# 这是修复后的rgl.window2user版本:
rgl.window2user <- function( x, y = NULL, z = 0, projection = rgl.projection()) {
xyz <- xyz.coords(x,y,z,recycle=TRUE)
viewport <- projection$view
normalized <- rbind( 2*(xyz$x - viewport[1]/viewport[3]) - 1,
2*(xyz$y - viewport[2]/viewport[4]) - 1,
2*xyz$z - 1,
1 )
asEuclidean(with(projection, t(solve(proj %*% model, normalized))))
}
environment(rgl.window2user) <- environment(rgl::rgl.window2user)
assignInNamespace("rgl.window2user", rgl.window2user, "rgl")
这样的代码在CRAN包中不被接受,但对于个人使用来说应该没问题。它所做的更改只在当前的R会话中生效。
英文:
This is a bug in the rgl.window2user()
function that is used by arrow3d()
. It has been fixed in rgl
1.1.10, but that's only available on Github, and installing rgl
from source isn't always easy. Here's a bit of a hack to install just the bug fix in the CRAN version 1.1.3:
# This is the fixed version of rgl.window2user:
rgl.window2user <- function( x, y = NULL, z = 0, projection = rgl.projection()) {
xyz <- xyz.coords(x,y,z,recycle=TRUE)
viewport <- projection$view
normalized <- rbind( 2*(xyz$x - viewport[1]/viewport[3]) - 1,
2*(xyz$y - viewport[2]/viewport[4]) - 1,
2*xyz$z - 1,
1 )
asEuclidean(with(projection, t(solve(proj %*% model, normalized))))
}
environment(rgl.window2user) <- environment(rgl::rgl.window2user)
assignInNamespace("rgl.window2user", rgl.window2user, "rgl")
Code like this is not accepted by CRAN in a package, but for your own use it should be okay. The change it makes will only last for the current R session.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论