# How can I combine my 3D graphics and animate them?

I'm just a beginner but can someone tell me how I can take my image of an Elf and put it together with a 3d background and I'm trying to animate it snowing but I wanna use a "play" button. Trying to do a short ten second one. Any ideas?

Import["http://i1.ytimg.com/vi/woHs5kFd3dI/maxresdefault.jpg"]

Graphics3D[{Red, Cone[],
White, Sphere[{0, 0, -1.5}, 1.03],
Red, Sphere[{0, 0, -3}, 1.09],
Red, Sphere[{1, 0, -2.8}, 1/4],
Sphere[{1.4, 0, -2.85}, 1/4.5],
Sphere[{1.7, 0, -2.95}, 1/4.9],
Sphere[{-1, 0, -2.8}, 1/4],
Sphere[{-1.4, 0, -2.85}, 1/4.5],
Sphere[{-1.7, 0, -2.95}, 1/4.9],
Yellow, Sphere[{1.9, 0, -3.1}, 1/5.3],
Sphere[{-1.9, 0, -3.1}, 1/5.3],
Black, Sphere[{-.5, -.80, -1.2}, 1/6],
Sphere[{.5, -.80, -1.2}, 1/6], Black,
Sphere[{-.3, -.84, -1.8}, 1/9],
Sphere[{.3, -.84, -1.8}, 1/9],
Sphere[{.15, -.84, -1.9}, 1/9],
Sphere[{-.15, -.84, -1.9}, 1/9],
Sphere[{0, -.84, -1.92}, 1/9],
Green, Sphere[{0, 0, 0}, .457],
Green, Sphere[{0, 0, -.5}, .68],
Green, Sphere[{0, 0, -1}, .901],
Sphere[{0, 0, 1}, 1/6],
Green, Sphere[{0, 0, .5}, .235],
Sphere[{0, -1, -3}, 1/7],
Green, Sphere[{0, -.87, -2.5}, 1/7],
Green, Sphere[{0, -.87, -3.5}, 1/7],
White, Sphere[{.9, 0, -1.5}, 1/4],
Sphere[{-.9, 0, -1.5}, 1/4]}]

Graphics3D[{Translate[flake,
Dynamic[With[{time = Clock[{0, 10, .05}]}, #@time & /@ funs]]]},
Boxed -> False, Lighting -> "Neutral", AxesLabel -> {"x", "y", "z"},
Background -> LightBlue, PlotRange -> {{-10, 10}, {-10, 10}, {0, 20}}

• Here is a related question that may give you some ideas: How to create animated snowfall? – Jens May 16 '14 at 2:05
• It seems that you shouldn't be using Dynamic because that's overkill (in fact, the last command is incomplete because funs is undefined). If you want a play button, you could use ListAnimate[frames] - where frames is the list of frames... – Jens May 16 '14 at 2:10
• What should I use instead of dynamics? I want to keep it very simple – Harunur Roshid May 16 '14 at 2:32
• I've put some of the ingredients into my answer - not including the snowfall, which you may want to do yourself because there are so many ways - you have to see which of the answers in the linked Q&A you like best... But my answer shows how ListAnimate works. – Jens May 16 '14 at 2:44

What you're trying to do requires several ingredients.

First, you want to define your elf so that it can be combined with other objects in a Graphics3D scene. This means you would just define the primitives making up the elf as follows:

elf = {Red, Cone[], White, Sphere[{0, 0, -1.5}, 1.03], Red,
Sphere[{0, 0, -3}, 1.09], Red, Sphere[{1, 0, -2.8}, 1/4],
Sphere[{1.4, 0, -2.85}, 1/4.5], Sphere[{1.7, 0, -2.95}, 1/4.9],
Sphere[{-1, 0, -2.8}, 1/4], Sphere[{-1.4, 0, -2.85}, 1/4.5],
Sphere[{-1.7, 0, -2.95}, 1/4.9], Yellow,
Sphere[{1.9, 0, -3.1}, 1/5.3], Sphere[{-1.9, 0, -3.1}, 1/5.3],
Black, Sphere[{-.5, -.80, -1.2}, 1/6],
Sphere[{.5, -.80, -1.2}, 1/6], Black,
Sphere[{-.3, -.84, -1.8}, 1/9], Sphere[{.3, -.84, -1.8}, 1/9],
Sphere[{.15, -.84, -1.9}, 1/9], Sphere[{-.15, -.84, -1.9}, 1/9],
Sphere[{0, -.84, -1.92}, 1/9], Green, Sphere[{0, 0, 0}, .457],
Green, Sphere[{0, 0, -.5}, .68], Green, Sphere[{0, 0, -1}, .901],
Sphere[{0, 0, 1}, 1/6], Green, Sphere[{0, 0, .5}, .235],
Sphere[{0, -1, -3}, 1/7], Green, Sphere[{0, -.87, -2.5}, 1/7],
Green, Sphere[{0, -.87, -3.5}, 1/7], White,
Sphere[{.9, 0, -1.5}, 1/4], Sphere[{-.9, 0, -1.5}, 1/4]};


Then you want a 2D image to be included in the Graphics3D scene. This can be done with the following convenience function, which takes the image (or other object) as its first argument s, and then places it with its upper left corner at 3D coordinate pos. The orientation of the upper edge coming out of that corner is defined by the next argument xVec. Also, the length of xVec is equal to the length of the horizontal axis with which your image will be displayed, in units of the 3D scene. So by making xVec longer, you scale up the whole image proportionally. The vertical edge of the image is tilted with respect to the vertical axis of the Graphics3D scene by an angle tiltAngle (it;s not needed here, so I set it to 0):

pic3D[s_, pos_, xVec_, tiltAngle_] :=
Module[{width, height, r},
r = Rasterize[Style[HoldForm[s], Magnification -> 10], "Image"];
{width, height} = ImageDimensions[r];
Translate[(* //to make lefthand corner pos*)
Rotate[(*   //around z axis*)
Rotate[(* //around y axis*)
Rotate[(* //tilt around x axis*)
Scale[(*//to make width equal|
xVec|*){EdgeForm[], Texture[ImageData@r],(* //
Texture fills polygon initially in the xz plane*)
Polygon[{{0, 0, 0}, {width, 0, 0}, {width, 0, height}, {0, 0,
height}},
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0,
1}}]}, Norm[xVec]/width, {0, 0, 0}],
tiltAngle, {1, 0, 0}],(* //x rotation*)
Arg[Chop@N[Norm[xVec[[1 ;; 2]] + I xVec[[3]]]]], {0, -1,
0}],(* //y rotation*)
Arg[Chop@N[xVec[[1]] + I xVec[[2]]]], {0, 0, 1}],(* //z rotation*)
pos]];


Now I'll combine the two objects defined above

pic = Import["http://i1.ytimg.com/vi/woHs5kFd3dI/maxresdefault.jpg"];
frames = Table[
Rasterize[
Graphics3D[{Rotate[elf, angle, {0, 0, 1}], Glow[White],
pic3D[pic, {-7, 5, -5}, {14, 0, 0}, 0]}, Boxed -> False ,
SphericalRegion -> True, ViewPoint -> {0, -10, -.5},
ViewAngle -> .05,
ImageSize -> {360, 200}],
"Image"],
{angle, 0, 2 Pi - Pi/10, Pi/10}];


Here I use Table to generate the frames where the angle of rotation of the elf is varied. In order to make the background image appear with its own "natural" color, I added the Glow[White] before inserting it with pic3D[pic,...] at a position that looks OK.

Edit: To improve the rendering in the animation, I added some steps in the above Table: First, reduce the ViewAngle and add an ImageSize option to Graphics3D so that the displayed region better matches the aspect ratio of the scene. Second, wrap each Graphics3D frame in Rasterize[..., "Image"] because this dramatically speeds up the subsequent ListAnimate. The animation then looks a little better that the GIF I uploaded (but I'll just leave the old GIF up for now).

Now make the animation. Unfortunately Mathematica is not very fast at rendering 3D graphics, so even the generation of the ListAnimate display will take some time.

ListAnimate[frames]


To create the gif, I did this:

Export["elf.gif", frames, "DisplayDurations" -> .07,
AnimationRepetitions -> Infinity]


Clearly, the quality could be improved, but I just want to show some basic steps.

• Forgot to say THANKS! GREATLY APPRECIATE IT! – Harunur Roshid May 19 '14 at 5:13