如何在 rgl plot3d 中绘制曲面
How to plot a surface in rgl plot3d
所以我有这段代码可以生成精确的表面
f = function(x, y){
z = ((x^2)+(3*y^2))*exp(-(x^2)-(y^2))
}
plot3d(f, col = colorRampPalette(c("blue", "white")),
xlab = "X", ylab = "Y", zlab = "Z",
xlim = c(-3, 3), ylim = c(-3, 3),
aspect = c(1, 1, 0.5))
给出以下情节:
现在我有一些代码可以执行随机游走大都会算法来重现上面的图像。我认为它的工作原理就好像我对这些计算值做了另一幅图,我得到了下一张 500 点的图像。这是代码
open3d()
plot3d(x0, y0, f(x0, y0), type = "p")
给出了以下情节:
我知道很难看这张静止图像,但能够旋转采样是可行的。
现在我的问题是:我如何使用 plot3d()
才能拥有一个连接所有这些点的表面,并给出更锯齿状的精确图?或者我怎样才能将 z 轴上的每个点作为 xy 平面的一个条?我只想要比点更多 3 维的东西,但我找不到如何做到这一点。
感谢您的帮助
我不确定你想要什么。如果我的理解是正确的,这里有一个解决方案。定义表面的参数表示:
fx <- function(u,v) u
fy <- function(u,v) v
fz <- function(u,v){
((u^2)+(3*v^2))*exp(-(u^2)-(v^2))
}
假设您有以下几点:
x0 <- seq(-3, 3, length.out = 20)
y0 <- seq(-3, 3, length.out = 20)
然后你可以使用misc3d
包的函数parametric3d
,加上选项fill=FALSE
得到一个线框:
library(misc3d)
parametric3d(fx, fy, fz, u=x0, v=y0,
color="blue", fill = FALSE)
是你想要的吗?
要获得一些垂直条,请使用 rgl
的函数 segments3d
:
i <- 8
bar <- rbind(c(x0[i],y0[i],0),c(x0[i],y0[i],f(x0[i],y0[i])))
segments3d(bar, color="red")
这是使用我的原始代码的只有 50 个点的情节。
然后当我应用 Stéphane Laurent 所说的话时,我得到了这个情节,当给出我的实际分数时感觉太准确了
也许你需要向我解释一下函数中实际发生了什么 parametric3d
您可以通过对表面进行三角测量来做到这一点。你没有给我们你的实际数据,但我可以使用
创建一些类似的数据
f = function(x, y){
z = ((x^2)+(3*y^2))*exp(-(x^2)-(y^2))
}
x <- runif(500, -3, 3)
y <- runif(500, -3, 3)
z <- f(x, y)
然后使用?persp3d.deldir
中的方法完成绘图:
library(deldir)
library(rgl)
col <- colorRampPalette(c("blue", "white"))(20)[1 + round(19*(z - min(z))/diff(range(z)))]
dxyz <- deldir::deldir(x, y, z = z, suppressMsge = TRUE)
persp3d(dxyz, col = col, front = "lines", back = "lines")
这可能需要一些修饰,例如
aspect3d(2, 2, 1)
经过一些轮换,这给了我以下情节:
所以我有这段代码可以生成精确的表面
f = function(x, y){
z = ((x^2)+(3*y^2))*exp(-(x^2)-(y^2))
}
plot3d(f, col = colorRampPalette(c("blue", "white")),
xlab = "X", ylab = "Y", zlab = "Z",
xlim = c(-3, 3), ylim = c(-3, 3),
aspect = c(1, 1, 0.5))
给出以下情节:
open3d()
plot3d(x0, y0, f(x0, y0), type = "p")
给出了以下情节:
现在我的问题是:我如何使用 plot3d()
才能拥有一个连接所有这些点的表面,并给出更锯齿状的精确图?或者我怎样才能将 z 轴上的每个点作为 xy 平面的一个条?我只想要比点更多 3 维的东西,但我找不到如何做到这一点。
感谢您的帮助
我不确定你想要什么。如果我的理解是正确的,这里有一个解决方案。定义表面的参数表示:
fx <- function(u,v) u
fy <- function(u,v) v
fz <- function(u,v){
((u^2)+(3*v^2))*exp(-(u^2)-(v^2))
}
假设您有以下几点:
x0 <- seq(-3, 3, length.out = 20)
y0 <- seq(-3, 3, length.out = 20)
然后你可以使用misc3d
包的函数parametric3d
,加上选项fill=FALSE
得到一个线框:
library(misc3d)
parametric3d(fx, fy, fz, u=x0, v=y0,
color="blue", fill = FALSE)
是你想要的吗?
要获得一些垂直条,请使用 rgl
的函数 segments3d
:
i <- 8
bar <- rbind(c(x0[i],y0[i],0),c(x0[i],y0[i],f(x0[i],y0[i])))
segments3d(bar, color="red")
这是使用我的原始代码的只有 50 个点的情节。
然后当我应用 Stéphane Laurent 所说的话时,我得到了这个情节,当给出我的实际分数时感觉太准确了
也许你需要向我解释一下函数中实际发生了什么 parametric3d
您可以通过对表面进行三角测量来做到这一点。你没有给我们你的实际数据,但我可以使用
创建一些类似的数据f = function(x, y){
z = ((x^2)+(3*y^2))*exp(-(x^2)-(y^2))
}
x <- runif(500, -3, 3)
y <- runif(500, -3, 3)
z <- f(x, y)
然后使用?persp3d.deldir
中的方法完成绘图:
library(deldir)
library(rgl)
col <- colorRampPalette(c("blue", "white"))(20)[1 + round(19*(z - min(z))/diff(range(z)))]
dxyz <- deldir::deldir(x, y, z = z, suppressMsge = TRUE)
persp3d(dxyz, col = col, front = "lines", back = "lines")
这可能需要一些修饰,例如
aspect3d(2, 2, 1)
经过一些轮换,这给了我以下情节: