[R] rgl how to plot a cylinder like arrow3d?

René Mayer mayer at psychologie.tu-dresden.de
Tue Aug 9 13:26:07 CEST 2011


Thanks Duncan!

yes! this works;
I paste the code in case someone wants to draw
3d-vectors with cylinders and cones.
René



vector3D=function(start=c(0,0,0), end, mycol='green', cone.length=0.1, ... ){
# ... cylinder as basis-vector
c=cylinder3d(rbind(      c(start), # start
			 c(0,0,1)), # end
		         radius = 0.4,
                          e1=cbind(0, 0, 1),
                          e2=cbind(1, 0, 0),
		         sides=10
                    )


# ... rotate cylinder horizontally and scale it
len=sqrt(sum(abs(end)*abs(end)))
c=scale3d(c,0.1,0.1,len-cone.length)

# ... Duncan Murdoch's code snipe
rotation <-  
rgl:::GramSchmidt(end-start+c(1,0,0),end-start+c(0,1,0),end-start,  
order=c(3,1,2))
c <- rotate3d(c, matrix=rotation)

shade3d(addNormals(c), col=mycol)

# ... cone3d from rgl-demos
q1 <- cone3d(qmesh=T,trans=diag(4))  # height=1,radius=1, base at (0,0,0)
q1=translate3d(scale3d(q1,0.15,0.15,1.4),0,0,len-cone.length)
q1=rotate3d(q1, matrix=rotation) # hinlegen ... negative rotation ==  
zeigerrrichtung
shade3d(q1,col=mycol) # verschachtelt aufrufen

}

open3d()
vector3D(start=c(0,0,0),end=data[,1], 'red');  
vector3D(start=c(0,0,0),end=data[,2],'green')
arrow3d(c(0,0,0),data[,1],color='red');arrow3d(c(0,0,0),data[,2],  
color='green')
axes3d(c('x','y','z'));title3d('main','sub','X','Y','Z');box3d()

> On 11-08-09 5:22 AM, René Mayer wrote:
>> Dear List,
>> I'm trying to draw vector in XYZ with rgl under use of a cylinder3d.
>> Therefore I scale and rotate a basis-cylinder).
>> However, somehow the rotation is wrong as
>> verified by overplotting arrow3d().
>> Where is my mistake?
>
> I would guess it is in assuming that theta can be computed on the  
> original vector, not on the rotated one:  rotating about the Y axis  
> changes end[1].
>
> I usually use a Gram-Schmidt type calculation to do this sort of  
> thing.  The undocumented rgl:::GramSchmidt function does this for  
> 3x3 matrices, orthogonalizing by row.  So you could replace all 3 of  
> your rotations (including the first one) by this:
>
> rotation <-  
> rgl:::GramSchmidt(end-start+c(1,0,0),end-start+c(0,1,0),end-start,  
> order=c(3,1,2))
> c <- rotate3d(c, matrix=rotation)
>
> (I notice you also forgot to translate the cylinders to start; this  
> doesn't matter in your example, but would if you had a non-zero  
> origin.)
>
> One problem with this kind of display is that it assumes the  
> coordinates are all of equal range.  If you try plotting one of  
> these vectors when the range of x, y and z are drastically  
> different, the cylinders will look really strange.
>
> Duncan Murdoch
>
>>
>> library(heplots)
>> library(rgl)
>>
>> # ... 2 vectors
>> data=data.frame(row.names=c('X','Y','Z'), x1=c(2,1,5),y=c(4,3,2))
>>
>> vector3D=function(start=c(0,0,0), end, mycol='green'){
>> # ... cylinder as basis-vector
>> c=cylinder3d(rbind(      c(start), # start
>> 			 c(0,0,1)), # end
>> 		         radius = 0.2,
>>                           e1=cbind(0, 0, 1),
>>                           e2=cbind(1, 0, 0),
>> 		         sides=10
>>                     )
>>
>> # ... rotate cylinder horizontally and scale it
>> len=sqrt(sum(abs(end)*abs(end)))
>> c=scale3d(c,0.1,0.1,len)
>> c=rotate3d(c,-(pi/2),0,1,0)
>>
>> # ... rotation angles
>> theta = atan2(end[2],end[1]) # angle in yx-plane for Z-achses rotation
>> phi = atan2(end[3],sqrt(end[1]^2+end[1]^2)) # angle in zx for Y-achses
>> rotation
>>
>> # ... rotation
>> c=rotate3d(c,phi,0,1,0) # Y-achses rotation
>> c=rotate3d(c, -theta,0,0,1) # Z-achses rotation
>> shade3d(addNormals(c), col=mycol)
>> }
>>
>> open3d()
>> vector3D(start=c(0,0,0),end=data[,1], 'red');
>> vector3D(start=c(0,0,0),end=data[,2],'green')
>> arrow3d(c(0,0,0),data[,1],color='red');arrow3d(c(0,0,0),data[,2],
>> color='green')
>> axes3d(c('x','y','z'));title3d('main','sub','X','Y','Z');box3d()
>>
>> thanks,
>> René
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>
>



More information about the R-help mailing list