# Mathematica, animations, and external ray tracing programs

As much as I enjoy and admire Mathematica's animation capabilities, I would like to take my animations to the next level by exporting the geometry of every frame to an external ray tracing program (say POV-Ray). Is there any easy way to do such a thing, i.e., without having to manipulate hundreds, or even thousands, of individual POV-Ray files? If so, what would the workflow look like for an animation project?

P.S. As an example of the things I'm interested in, here's some code for a project I've been doing. It depicts a plane falling into a cone, together with the resulting hyperbola.

Clear["Global*"];

x1[t_] := -((16*(290 - 15*Sqrt[29]*Cosh[t] + 2*Sqrt[3103]*Sinh[t]))/3103)
y1[t_] := (16*(-116 + 6*Sqrt[29]*Cosh[t] + 5*Sqrt[3103]*Sinh[t]))/3103
z1[t_] := 5*x1[t] + 2*y1[t] + 8
x2[t_] := -((16*(290 + 15*Sqrt[29]*Cosh[t] + 2*Sqrt[3103]*Sinh[t]))/3103)
y2[t_] := (16*(-116 - 6*Sqrt[29]*Cosh[t] + 5*Sqrt[3103]*Sinh[t]))/3103
z2[t_] := 5*x2[t] + 2*y2[t] + 8
boven1 = Flatten[{{x, y} /. Solve[{(9/4)*(x^2 + y^2) == 21^2, 5*x + 2*y + 8 == 21}, {x,    y}][[1]], 21}];
boven2 = Flatten[{{x, y} /. Solve[{(9/4)*(x^2 + y^2) == 21^2, 5*x + 2*y + 8 == 21}, {x, y}][[2]], 21}];
m1 = (boven1 + boven2)/2;
onder1 = Flatten[{{x, y} /. Solve[{(9/4)*(x^2 + y^2) == 21^2, 5*x + 2*y + 8 == -21}, {x, y}][[1]], -21}];
onder2 = Flatten[{{x, y} /. Solve[{(9/4)*(x^2 + y^2) == 21^2, 5*x + 2*y + 8 == -21}, {x, y}][[2]], -21}];
m2 = (onder1 + onder2)/2;
distance[{start_, end_}, pt_] := Module[{param}, param = (pt - start) . (end - start)/Norm[end - start]^2; Which[param < 0, EuclideanDistance[start, pt], param > 1,
EuclideanDistance[end, pt], True, EuclideanDistance[pt, start + param*(end - start)]]];

Export["hyperbola.mov", Table[Show[
Graphics3D[{Opacity[.4], RGBColor[1, 1, 1], Specularity[White, 100],
Sphere[{0, 0, 1.95}, 1.08]}, Boxed -> False],
Graphics3D[{Opacity[.4], RGBColor[1, 1, 1], Specularity[White, 100],
Sphere[{0, 0, -3.95}, 2.18]}, Boxed -> False],
ParametricPlot3D[{x1[t], y1[t], z1[t]}, {t, -1.82306, 1.82306},
RegionFunction -> Function[{x, y, z}, z >= 7 - u], PlotStyle -> {Yellow},
Method -> {"TubePoints" -> 1}] /.
Line[pts_, rest___] :> Tube[pts, 0.08, rest],
ParametricPlot3D[{x2[t], y2[t], z2[t]}, {t, -1.61735, 1.61735},
RegionFunction -> Function[{x, y, z}, z >= 7 - u], PlotStyle -> {Yellow},
Method -> {"TubePoints" -> 1}] /.
Line[pts_, rest___] :> Tube[pts, 0.08, rest],
ParametricPlot3D[{0.895 Cos[t], 0.895 Sin[t], 1.342}, {t, 0, 2 Pi},
Boxed -> False, Axes -> False, PlotStyle -> {Yellow},
Method -> {"TubePoints" -> 2}] /.
Line[pts_, rest___] :> Tube[pts, 0.02, rest],
ParametricPlot3D[{1.86 Cos[t], 1.86 Sin[t], -2.79}, {t, 0, 2 Pi},
Boxed -> False, Axes -> False, PlotStyle -> {Yellow},
Method -> {"TubePoints" -> 2}] /.
Line[pts_, rest___] :> Tube[pts, 0.02, rest],
Plot3D[5 x + 2 y + 8, {x, -9, 9}, {y, -9, 9},
RegionFunction ->
Function[{x, y, z},
z <= 21.1 - u && z >= 6.9 - u && distance[{m1, m2}, {x, y, z}] <= 6],
PlotStyle ->
Directive[Opacity[.55], Specularity[White, 100], RGBColor[1, 0, 0]],
BoundaryStyle -> {Thickness[0.003], Yellow}, Mesh -> False, Boxed -> False,
Axes -> False, PlotPoints -> 200],
Graphics3D[{Opacity[.6], Specularity[White, 200], RGBColor[0, 0, 1/2],
EdgeForm[{Thickness[0.003], Yellow}],
Cone[{{0, 0, -7}, {0, 0, 0}}, 4*7/6]}, Boxed -> False],
Graphics3D[{Opacity[.6], Specularity[White, 200], RGBColor[0, 0, 1/2],
EdgeForm[{Thickness[0.003], Yellow}],
Cone[{{0, 0, 7}, {0, 0, 0}}, 4*7/6]}], ImageSize -> {2000, 2000},
Lighting -> {{"Point", White, {10, 0, 0}}, {"Point",
White, {-10, 0, 0}}, {"Point", White, {0, 0, 0}}, {"Point",
White, {0, 0, 10}}, {"Point", White, {0, 0, -10}}}, Background -> Black,
ViewVector -> {{20 Sin[1.15 Pi + u], 20 Cos[1.15 Pi + u], 10}, {0, 0, 0}},
ViewAngle -> 50 \[Degree]], {u, -3, 14, .05}]]


• this only depends on format of input files your pov-ray needs.. why you don't specify it? btw, the simplest i think would be just to export some mesh points which demonstrate physically accurate movement and import it directly in some software like 3ds max, maya, blender with appropriate rendering system (vray, mental ray, etc.)- after several tweaks you can get any quality you want. Nov 26, 2014 at 15:26
• Thanks, funnypony. The reason I like POV-Ray so much is that it's entirely text-based and doesn't involve having to fidget about with my mouse (I hate that). I would be happy if I could get Mathematica to prefix each POV-Ray export (which Mathematica supports, by the way) with a preamble in which I specify camera, lighting, etc. But unfortunately I don't know to what extent it's possible to customize Mathematica's export facilities. Nov 26, 2014 at 16:58

I would be happy if I could get Mathematica to prefix each POV-Ray export (which Mathematica supports, by the way) with a preamble in which I specify camera, lighting, etc. But unfortunately I don't know to what extent it's possible to customize Mathematica's export facilities.

Use ExportString for obtaining the output file as a String inside of Mathematica, then you can manipulate that string the way you want: prepend another string with StringJoin, change the string with StringReplace etc. Finally you can simply Export that string as "Text" into a file with any extension you like.

BTW, I am interested in the ability to render Mathematica's 3D graphics in external ray-tracing software too. What stops me is only that I know nothing about how to use/work with any of them and how their formats are designed. But I would be happy to find out.

• Thanks! I hadn't thought about that one yet. That's brilliant and exactly what I want. Nov 26, 2014 at 21:03
• If you find a sufficiently general way to "fix" Mathematica's Export for nice rendering in POV-Ray I encourage you to share with us a solution (via a self-answered question or via another answer in this thread). I predict many upvotes since many of us lack this functionality. Nov 26, 2014 at 21:08
• Sure I will, Alexey. I'll get to work on it as soon as time permits. I do think that POV-Ray is the best suited ray tracer for my purposes (large number of automated exports), because, as I said, it's entirely text-based and thus offers at least a remote possibility that the task can be accomplished without any direct personal manipulation of individual files (which would be prohibitive in both time and effort). Nov 26, 2014 at 21:25

I don't know how much you have worked with POVRay, but there is no need to generate thousands of individual pov files. For animations you can use the built-in clock function. Include in the graphics primitives exported by Mathematica a dependence on the clock, and let POVRay do the work for you. The following is a very simple example of POVRay code which generates frames for a subsequent animation. Ugly images, for illustration only. Note the "clock" variable in the specification of the plane.

global_settings { assumed_gamma 1.0 }

camera { location <0,30,-100> look_at <0,0,0> angle 10
up y*image_height right x*image_width look_at <0, 0, 0> }

light_source { <100,200,-200> color 1 shadowless}

intersection {
union {
cone {<0, -5, 0>, 5.00, <0, 0, 0>, 0.01 open texture{T_Stone21 scale 2}}
cone {<0,  0, 0>, 0.01, <0, 5, 0>, 5.00 open texture{T_Stone21 scale 2}}
}
plane {<-15, 5, -15>, 10*clock-5.0 texture{T_Stone18 scale 4}}
}


On the command line run:

povray example.pov +w400 +h400 +KI0.0 +KF1.0 +KFI1 +KFF30 +FP +Oexample.ppm
`

The clock is set here to run from 0.0 to 1.0, and 30 frames are rendered, with names examplenn.ppm. I use ppmtompeg to convert the *.ppm files to an mpg. Beware that Mathematica exports pov files with apparently all colours set to white. See here.

• Wow, thanks! I didn't know that it was possible to make Mqthematica graphics dependent on POV-Ray's clock variable. What would the corresponding Mathematica code look like? Nov 26, 2014 at 23:19
• Unfortunately, not that easy. Export the Mathematica graphic as pov code, then edit that code with clock functions. Depends on how simple your original graphic is. For my images, I use Mathematica to write strings of pov primitives directly. That way I have full control, and get the colours too. Nov 27, 2014 at 5:05