11

我有一条我正在使用 R 制作的曲线(参见下面的代码):

library(rgl)

y = seq(-5,25,by=0.01)
x = seq(5,20,by=0.02)

sd = 0.3*x
NAs <- rep(NA, length(x)*length(y))
z <- matrix(NAs, length(x), byrow = T)
for(i in seq(1,length(x))) {
    for(j in seq(1,length(y))) {
        val = dnorm(y[j],mean=7.5,sd=sd[i])     
        z[i,j] = val
        if(z[i,j] < 0.02) {
            z[i,j] = NA
        }
    }
}

col <- rainbow(length(x))[rank(x)]        

open3d()
persp3d(x,y,z,color=col,xlim=c(5,20),ylim=c(5,10),axes=F,box=F,xlab="exp",ylab="obs",zlab="p")

这就是它的作用: 在此处输入图像描述

稍微旋转一下,就可以看到这是一个空心管型的人偶。

在此处输入图像描述

但我试图让它被填充(用颜色渐变),这样它就不是空心的。想象一下在任何位置进行切片,如果有意义的话,你会得到一个 2D 平面,而不是 2D 曲线。我怎样才能做到这一点?

4

2 回答 2

7

要填充 3-d 中的间隙(2-d 形状),您不应该使用线条,因为它们是 1-d 对象。用三角形或四边形(具有四个角的平面对象)填充间隙。

library(rgl)

y <- seq(-5,25,by=0.1)
x <- seq(5,20,by=0.2)
z <- outer(.3*x, y, function(my.sd, my.y) dnorm(my.y, mean=7.5, sd=my.sd))
z[z < .02] <- NA

col <- rainbow(length(x))[rank(x)]        
xn <- length(x)
yn <- length(y)

open3d()
persp3d(x, y, z, color=col, xlim=c(5,20), ylim=c(5,10), axes=F, box=F,
        xlab="exp", ylab="obs", zlab="p")
rgl.quads(rep(x[xn], (yn-1)*4),
          sapply(2:yn, function(i) y[i-c(0:1,1:0)]),
          sapply(2:yn, function(i) c(z[xn,i-0:1], 0, 0)),
          color=col[xn])

在此处输入图像描述

如果您对 R 不太熟悉,and 命令可能会让人感到困惑,但可以将它们视为矢量化outer循环。该调用对坐标进行外连接以一次性创建所有内容,并且s 提取四边形的坐标。在 R(或任何其他高级非编译语言)中避免循环的原因是它们非常慢并且还使代码变得庞大。sapplyforouterzsapplyfor

于 2013-02-28T09:16:27.710 回答
6

在花费大量时间找出更优雅的东西之后,最好的方法是手动添加行来填补空白:

yy = seq(-5, 25, by=0.01)
xx = rep(5,length(yy))
sds = 0.7 * xx
val = rep(NA, length(xx))
for(i in seq(1,length(val))) {
    val[i] = dnorm(yy[i],mean=rep(7.5,length(xx[i])),sd=sds[i])
    t = 0.06
    if(val[i] > 0.02) {
        #val[i] = t
        lines3d(c(xx[i],xx[i]),c(yy[i],yy[i]),c(0.02,val[i]),color="red")
    }
}
于 2013-02-24T18:40:28.273 回答