【问题标题】:How to plot a surface in rgl plot3d如何在 rgl plot3d 中绘制曲面
【发布时间】:2018-11-20 17:10:48
【问题描述】:

所以我有这段代码可以产生精确的表面

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 维的东西,但我找不到如何做到这一点。

感谢您的帮助

【问题讨论】:

    标签: r rgl


    【解决方案1】:

    您可以通过对表面进行三角测量来做到这一点。你没有给我们你的实际数据,但我可以创建一些类似的数据使用

    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)
    

    经过一些旋转,这给了我以下情节:

    【讨论】:

    • 我认为这给出了最接近我正在寻找的东西,并且没有像其他答案一样向数据添加额外的点,所以这非常好,谢谢
    【解决方案2】:

    我不确定你想要什么。如果我的理解是正确的,这里有一个解决方案。定义表面的参数表示:

    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")
    

    【讨论】:

    • Hmm... 最后我认为parametric3d 是不合适的,因为它从x0y0 创建了一个点网格。但也许可以修改源代码以获得适当的东西。
    • 哇,不,我认为这很好,谢谢!我会尝试类似的东西,看看它的外观,但我会再试一次。我想要的是通过网络连接所有点,这看起来很有希望。我也是包和语言的新手,所以我不确定包中的哪些功能可以满足我的需求,但我认为你的知识对我有所帮助。
    • @MRT 我不确定...parametric3d 你给x0y0 点是网格expand.grid(x0, y0) 的点。 x0y0 没有必要具有相同的长度。在您的情况下,您不需要网格。
    • 是的,我不想要一个网格,但我刚刚尝试以我的 1000 点分辨率运行它,所有这些都合并在一起形成一个平滑的蓝色表面。我想问的一个问题是,您对parametric3d 这个函数了解得够多,可以告诉我如何像问题中的散点图那样设置方框?
    • 哦等等有问题。当我只使用几个点时,表面应该看起来更加锯齿状,但我无法显示图像,所以我会在此之后发布一个新的答案
    【解决方案3】:

    这是一个使用我的原始代码只有 50 个点的图。

    当我应用 Stéphane Laurent 所说的话时,我会得到这个情节,当给出我的实际分数时感觉太准确了

    也许你需要向我解释一下函数parametric3d中实际发生的事情

    【讨论】:

    • 我已经解释过了 :-) 例如,当您给出 x0 = c(1,2)y0=c(3,4) 时,然后 parametric3d 使用点 c(1,3), c(1,4), c(2,3) , c(2,4)(通过x0y0“交叉”得到的网格,也就是笛卡尔积)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 2012-02-02
    • 1970-01-01
    相关资源
    最近更新 更多