如何在R中绘制三维箭头?
我正在使用rgl软件包创建数据的3D绘图。出于某些原因(3D PCA双图),我需要向量——带箭头的线段。我被卡住了,因为我想用3D圆锥体作为箭头 不知何故,我无法把我的老朽思想围绕在问题的几何学上。比方说,我会用如何在R中绘制三维箭头?,r,graphics,vector,3d,R,Graphics,Vector,3d,我正在使用rgl软件包创建数据的3D绘图。出于某些原因(3D PCA双图),我需要向量——带箭头的线段。我被卡住了,因为我想用3D圆锥体作为箭头 不知何故,我无法把我的老朽思想围绕在问题的几何学上。比方说,我会用 segments3d( rbind( c( 0, 0, 0 ), c( 3, 3, 3 ) ) ) 即,从用户坐标系原点到[3,3,3]的向量 我想创建一个尖端位于[3,3,3]的圆锥体。圆锥体的底部可以形成一个圆。在xz平面(垂直于y平面)上绘制半径为r的圆很容易: n <-
segments3d( rbind( c( 0, 0, 0 ), c( 3, 3, 3 ) ) )
即,从用户坐标系原点到[3,3,3]的向量
我想创建一个尖端位于[3,3,3]的圆锥体。圆锥体的底部可以形成一个圆。在xz平面(垂直于y平面)上绘制半径为r的圆很容易:
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
n在rgl的演示中,有一个cone3d函数。它把底部和尖端分开。在任何情况下,您都可以这样做:
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函数:
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))
}
cone3d