[R] rgl package and animation

Robert Baer rbaer at atsu.edu
Sat Nov 3 16:40:15 CET 2012


On 11/3/2012 6:47 AM, Duncan Murdoch wrote:
> On 12-11-02 7:47 PM, Robert Baer wrote:
>> I am trying to figure out how to use rgl package for animation.  It
>> appears that this is done using the play3d() function.  Below I have
>> some sample code that plots a 3D path and puts a sphere at the point
>> farthest from the origin (which in this case also appears to be at the
>> end of the path).  What I would like to do is animate the movement of
>> another sphere along the length of the path while simultaneously
>> rotating the viewport.
>>
>> Duncan Murdock's (wonderful) Braided Knot YouTube video:
>>    (http://www.youtube.com/watch?v=prdZWQD7L5c)
>> makes it clear that such things can be done, but I am having trouble
>> understanding how to construct the f(time) function that gets passed to
>> play3d().  The demo(flag) example is a little helpful, but I still can't
>> quite translate it to my problem.
>>
>> Can anyone point to some some simple f(time) function examples that I
>> could use for reference or give me a little hint as to how to construct
>> f(time) for movement along the path while simultaneously rotating the
>> viewport?
>>
>> Thanks,
>>
>> Rob
>>
>>
>>
>> library(rgl)
>> # Generate a 3D path
>> dat <-
>> structure(list(X = c(0, 0.0618130000000008, 0.00223599999999635,
>> -0.0308069999999958, -0.172805999999994, -0.372467, -0.587706999999995,
>> -0.881484999999998, -1.103668, -1.366157, -1.625862, -1.94806699999999,
>> -2.265388, -2.68982699999999, -3.095001, -3.49749, -3.946068,
>> -4.395653, -4.772034, -5.111259, -5.410515, -5.649475, -5.73439,
>> -5.662201, -5.56714599999999, -5.39033499999999, -5.081581, -4.796631,
>> -4.496559, -4.457024, -4.459564, -4.641746, -4.84910599999999,
>> -5.08994300000001, -5.43129, -5.76372499999999, -6.199448, -6.517578,
>> -6.86423499999999, -6.90743999999999), Y = c(0, -0.100724,
>> -0.169471999999999,
>> 0.0365059999999886, -0.0929950000000019, -0.222977, -0.355759000000006,
>> -0.365822000000009, -0.329948999999999, -0.209557000000004,
>> -0.0804140000000046,
>> 0.0201339999999988, 0.295372, 0.138831999999994, 0.281104999999997,
>> 0.223761999999994, 0.141905999999992, 0.0602949999999964,
>> -0.0933080000000075,
>> -0.207596000000009, -0.328629000000006, -0.438568000000004,
>> -0.469109000000003,
>> -0.623505000000009, -0.525467000000006, -0.568444, -0.638885999999999,
>> -0.727356, -1.073769, -1.03213500000001, -1.203461, -1.438637,
>> -1.65023100000001, -1.861351, -2.169083, -2.43147300000001,
>> -2.69914300000001,
>> -2.961258, -3.23938000000001, -3.466103), Z = c(0, 0.13552900000002,
>> 0.401062000000024, 1.21637000000004, 1.55395500000003, 1.73080500000003,
>> 1.81167600000003, 2.18512000000004, 2.52603200000004, 3.03479000000004,
>> 3.42654400000004, 3.82251000000002, 4.74490400000002, 4.644837,
>> 5.41848800000002, 5.85867300000001, 6.37835699999999, 6.83395400000001,
>> 7.216339, 7.59411600000004, 7.95590200000004, 8.352936, 
>> 8.70931999999999,
>> 9.01669300000003, 9.48553500000003, 9.90005500000001, 10.397003,
>> 10.932068, 11.025726, 12.334595, 13.177887, 13.741852, 14.61142,
>> 15.351013, 16.161255, 16.932831, 17.897186, 18.826691, 19.776001,
>> 20.735596), time = c(0, 0.0100000000000016, 0.0199999999999996,
>> 0.0300000000000011, 0.0399999999999991, 0.0500000000000007,
>> 0.0600000000000023,
>> 0.0700000000000003, 0.0800000000000018, 0.0899999999999999,
>> 0.100000000000001,
>> 0.109999999999999, 0.120000000000001, 0.129999999999999, 
>> 0.140000000000001,
>> 0.150000000000002, 0.16, 0.170000000000002, 0.18, 0.190000000000001,
>> 0.199999999999999, 0.210000000000001, 0.220000000000002, 0.23,
>> 0.240000000000002, 0.25, 0.260000000000002, 0.27, 0.280000000000001,
>> 0.289999999999999, 0.300000000000001, 0.310000000000002, 0.32,
>> 0.330000000000002, 0.34, 0.350000000000001, 0.359999999999999,
>> 0.370000000000001, 0.379999999999999, 0.390000000000001)), .Names = 
>> c("X",
>> "Y", "Z", "time"), row.names = c("1844", "1845", "1846", "1847",
>> "1848", "1849", "1850", "1851", "1852", "1853", "1854", "1855",
>> "1856", "1857", "1858", "1859", "1860", "1861", "1862", "1863",
>> "1864", "1865", "1866", "1867", "1868", "1869", "1870", "1871",
>> "1872", "1873", "1874", "1875", "1876", "1877", "1878", "1879",
>> "1880", "1881", "1882", "1883"), class = "data.frame")
>>
>>
>> # Plot 3d path
>> with(dat, plot3d(X,Y,Z, type = 'l', col = 'blue', lty = 1))
>>
>> # get absolute distance from origin
>> dat$r = sqrt(dat$X ^ 2 + dat$Y ^ 2 + dat$Z ^ 2)
         mr = max(dat$r)  # yes sorry, didn't get copied to original 
email code
>> mxpnt = dat[dat$r == mr,] # Coordinates of furthest point
>>
>> # Plot a blue sphere at max distance
>> plot3d(mxpnt$X, mxpnt$Y, mxpnt$Z, type = 's', radius = 1, col = 'blue',
>> add = TRUE)
>>
>
> Your code didn't include the mr variable, but I assume it's just 
> max(dat$r).  With that assumption, I'd do the animation function as 
> follows:
>
> First, draw the new sphere at the first point and save the object id:
>
> sphereid <- sphere3d(dat[1,c("X", "Y", "Z")], col="red", radius=1)
>
> # Also save the spinner that you like:
>
> spin <- spin3d( ) #maybe with different parms
>
> # Now, the animation function:
>
> f <- function(time) {
>   par3d(skipRedraw = TRUE) # stops intermediate redraws
>   on.exit(par3d(skipRedraw=FALSE)) # redraw at the end
>
>   rgl.pop(id=sphereid) # delete the old sphere
>   pt <- time %% 40 + 1 # compute which one to draw
>   pnt <- dat[pt, c("X", "Y", "Z")] # maybe interpolate instead?
>   sphereid <<- spheres3d(pnt, radius=1, col="red")
>   spin(time)
> }
>
> Duncan Murdoch

Thanks so much Duncan!

I probably never would have gotten there without your help. (Especially 
since I had to look at the help for the <<- operator, which is 
conceptually a level beyond where I usually work).   It would be great 
to have an additional creative example or two for  f(time) functions in 
the play3d() help.  Your useful code comments really help me see what 
needs to happen in an f(time) function.

I really appreciate that you took the time to get me going!

Rob




More information about the R-help mailing list