2013-03-01 20 views
5

Verilerimin 3B grafiklerini oluşturmak için rgl paketini kullanıyorum. Bazı nedenlerden dolayı (3D PCA pankartları) vektörlere ihtiyacım var - ok içeren bir çizgi parçası. Ve ben sıkışıp kaldım, çünkü 3D konileri ok başı olarak kullanmak istiyorum.R'de nasıl bir 3D ok çizebilirim?

Bir şekilde, senil fikrimi sorunun geometrisi etrafına saramam. I olduğu, kullanıcının kökenli bir vektör [3,3,3] koordinat sistemine

segments3d(rbind(c(0, 0, 0), c(3, 3, 3))) 

ile vektör çekecektir, de.

[3,3,3] 'de ipucu olan bir koni oluşturmak istiyorum. Koninin tabanı bir daire ile oluşturulabilir. r yarıçaplı (y düzlemine dik) xz düzleminde bir daire Çizim kolaydır: daire vektörüne dik artık

n <- 10 
sin.t <- sin(seq(0, 2 * pi, len= n)) 
cos.t <- cos(seq(0, 2 * pi, len= n)) 
r <- 0.1 
xv <- x + r * sin.t 
yv <- rep(y, n) 
zv <- z + r * cos.t 

ama nasıl hemen dönüştürmek do bu noktalar öyle ki? Ve merkezi 0.2 vektörler boyunca uçtan? Bu dönüşüme sahip olduğumda, triangles3d işleviyle üçgenler çizeceğim, her üçgen uçta bir köşeye ve dairenin noktaları içinde iki köşeye sahip olacak.

Bu temel matematiktir ve 18 yaşındaki bir çocuğun benim bir problemim olmadığını (hatta 28 yaşında bir ben bile) bilmiyorum. Herhangi bir kanca (balıkların aksine) takdir edilecektir.

cevap

7

Rgl için demolarda bir cone3d işlevi vardır. Taban ve ucu ayrı ayrı alır. Her durumda böyle bir şey yapabileceğini:

cone3d <- function(base=c(0,0,0),tip=c(0,0,1),rad=1,n=30,draw.base=TRUE,qmesh=FALSE, 
        trans = par3d("userMatrix"), ...) { 
    ax <- tip-base 
    if (missing(trans) && !rgl.cur()) trans <- diag(4) 
    ### is there a better way? 
    if (ax[1]!=0) { 
    p1 <- c(-ax[2]/ax[1],1,0) 
    p1 <- p1/sqrt(sum(p1^2)) 
    if (p1[1]!=0) { 
     p2 <- c(-p1[2]/p1[1],1,0) 
     p2[3] <- -sum(p2*ax) 
     p2 <- p2/sqrt(sum(p2^2)) 
    } else { 
     p2 <- c(0,0,1) 
    } 
    } else if (ax[2]!=0) { 
    p1 <- c(0,-ax[3]/ax[2],1) 
    p1 <- p1/sqrt(sum(p1^2)) 
    if (p1[1]!=0) { 
     p2 <- c(0,-p1[3]/p1[2],1) 
     p2[3] <- -sum(p2*ax) 
     p2 <- p2/sqrt(sum(p2^2)) 
    } else { 
     p2 <- c(1,0,0) 
    } 
    } else { 
    p1 <- c(0,1,0); p2 <- c(1,0,0) 
    } 
    degvec <- seq(0,2*pi,length=n+1)[-1] 
    ecoord2 <- function(theta) { 
    base+rad*(cos(theta)*p1+sin(theta)*p2) 
    } 
    i <- rbind(1:n,c(2:n,1),rep(n+1,n)) 
    v <- cbind(sapply(degvec,ecoord2),tip) 
    if (qmesh) 
    ## minor kluge for quads -- draw tip twice 
    i <- rbind(i,rep(n+1,n)) 
    if (draw.base) { 
    v <- cbind(v,base) 
    i.x <- rbind(c(2:n,1),1:n,rep(n+2,n)) 
    if (qmesh) ## add base twice 
     i.x <- rbind(i.x,rep(n+2,n)) 
    i <- cbind(i,i.x) 
    } 
    if (qmesh) v <- rbind(v,rep(1,ncol(v))) ## homogeneous 
    if (!qmesh) 
    triangles3d(v[1,i],v[2,i],v[3,i],...) 
    else 
    return(rotate3d(qmesh3d(v,i,material=...), matrix=trans)) 
}  
: Burada
vec=rbind(c(0, 0, 0), c(3, 3, 3)) 
segments3d(vec) 


cone3d(base=vec[2,]-(vec[1,]+vec[2,]/6), 
    #this makes the head go 1/6th the length of the arrow 
     rad=0.5, 
     tip=vec[2,], 
     col="blue", 
     front="lines", 
     back="lines") 

cone3d fonksiyonudur
İlgili konular