Modelling Prehistoric Life

This interpolating function generates the shape of the curve to be used for the fins.

fun = 
        Interpolation[{{0, 0.2}, {0.6, 0.35}, {0.75, 0.35}, {0.9, 
              0.25}, {0.95, 0.15}, {1,  .01}}, 
          InterpolationOrder -> 2];

Here's the front edge in 2D.

front = Table[{x, fun[x]}, {x, 0, 1,  .1}];

This mirrors the frontedge to make the backedge, removing the pivot point in the process and joins the points together.

flatpoly = 
        Join[front, 
          Drop[Reverse[front], {-1}] /. {x_, 
                y_} -> {x, -y}];

This creates the top 3D polygon vertices resulting in a polygon tilted in the y-direction.

toppoly = 
        flatpoly /. {x_, y_} -> {x, 
              y,  .5 ( .025 + y)};

This creates the bottom 3D polygon.

bottompoly = 
        toppoly /. {x_, y_, z_} -> {x, y, z -  .025};

Because the fins need to "flap", and to prevent non-planar polygons later, we use code to break up the fin polygon into triangles that can be transformed more easily without distortion.

MyTriangles[pts_] := 
        Module[{c = Total[pts]/Length[pts]}, 
          Table[{c, pts[[i]], pts[[Mod[i + 1, Length[pts], 1]]]}, {i, 
              Length[pts]}]];

topfin = MyTriangles[flatpoly];

This transforms the 2D polygon into a 3D polygon that it tilted slightly in the y-direction.  This allows the fins to overlap without intersecting all of the time.

topside = 
        topfin /. {x_, y_} -> {x, y,  .5 ( .025 + y)};

This creates the bottom of the side-fins.

bottomside = 
        topside /. {x_?NumberQ, y_?NumberQ, z_?NumberQ} -> {x, y, 
              z -  .025};

This fills in the gap between the top and bottom of the fins.

sides = 
        Table[{toppoly[[i]], toppoly[[i + 1]], 
            bottompoly[[i + 1]], bottompoly[[i]], 
            toppoly[[i]]}, {i, 1, Length[topfin] - 1}];

Now, we convert the vertices into polygons and create a fin that can be translated in x, y, and z.

mycolor = RGBColor[ .9,  .6,  .4];

fin[x_, y_, z_] := 
      Graphics3D[{EdgeForm[], SurfaceColor[mycolor], Map[Polygon, sides], 
            Map[Polygon, topside], Map[Polygon, bottomside]}, 
          Axes -> True, 
          ImageSize -> 400] /. {oldx_?NumberQ, oldy_?NumberQ, 
            oldz_?NumberQ} :> {oldx + x, oldy + y, 
            oldz + z}

Here is what a single fin looks like.

Show[fin[0, 10, 0], 
      LightSources -> {{{1, 1, 1}, White}}]

Here we define an ellipsoid to be used to model the head of Anomalocaris.

Ellipsoid[a_, b_, 
        c_, {x_, y_, z_}] := {a Cos[θ] Sin[ϕ] + x, 
        b Sin[θ] Sin[ϕ] + y, 
        c Cos[ϕ] + z, {EdgeForm[], mycolor}}

The mouth is modelled using ParametricPlot3D.

mouth = 
        Show[ParametricPlot3D[{r Cos[t], 
              r Sin[t] + 2.75, - .43, {EdgeForm[], 
                mycolor}}, {r,  .1,  .25}, {t, 0, 2 π}, 
            PlotPoints -> 30, DisplayFunction -> Identity], 
          ParametricPlot3D[{r Cos[t], 
              r Sin[t] + 2.75, - .48, {EdgeForm[], 
                mycolor}}, {r,  .1,  .25}, {t, 0, 2 π}, 
            PlotPoints -> 30, DisplayFunction -> Identity], 
          ParametricPlot3D[{ .1 Cos[t],  .1 Sin[t] + 2.75, 
              z, {EdgeForm[], mycolor}}, {z, - .48, - .43}, {t, 0, 
              2 π}, PlotPoints -> 30, 
            DisplayFunction -> Identity], 
          ParametricPlot3D[{ .25 Cos[t],  .25 Sin[t] + 2.75, 
              z, {EdgeForm[], mycolor}}, {z, - .48, - .43}, {t, 0, 
              2 π}, PlotPoints -> 30, 
            DisplayFunction -> Identity]];

Now, we construct the model using the fins, mouth, ellipsoid, sphere and cylinder objects, lighting, and viewpoint settings.  The oscillation effect is obtained by transforming the vertices using sinusoids.

myCylinder[p1_, p2_, 
        r_] := 
Module[{gc, len, v, n1, n2, n1y, n1z, n2x, 
          n2y, n2z}, 

 (* 
          Calculate Normals *) 
len = 
          Norm[p2 - p1]; 
v = 
          N[(p2 - p1)/len]; 
If[
          MatchQ[v, {x_, 0. , 0. }], 
{n1, 
              n2} = {{0, 1, 0}, {0, 0, 1}}; , 
{n1, 
              n2} = {{0, n1y, n1z}, {n2x, n2y, n2z}}; 
n1 = 
            n1 /. First[
                Solve[{n1 . v == 0, n1 . n1 == v . v}, {n1y, 
                    n1z}]]; 
n2 = 
            n2 /. First[
                Solve[{n2 . v == 0, n2 . n1 == 0, 
                    n2 . n2 == v . v}, 
                  n2]]; 
]; 

 (* 
          Create Cylinder *) 
ParametricPlot3D[(h v + r Sin[t] n1 + r Cos[t] n2) + (p1 + (p2 - p1)/2), {h, -len/
                2, len/2}, {t, 0, 2 π}, PlotPoints -> 15, 
            DisplayFunction -> 
              Identity][[1]]
]

mySphere[{a_, b_, c_}, 
        rad_] := ParametricPlot3D[{rad Sin[v] Cos[u] + a, 
            rad Sin[v] Sin[u] + b, rad Cos[v] + c}, {u, 0, 2 π}, {v, 
            0, π}, DisplayFunction -> Identity, 
          PlotPoints -> 15][[1]]

Here's one frame.

With[{t = 0}, 
      Show[{Graphics3D[{EdgeForm[], SurfaceColor[mycolor, White, 5], 
                First@mouth, 
                First@ParametricPlot3D[
                    Ellipsoid[ .45,  .85,  .45, {0, 2.65, 0}], {θ, 0, 
                      2  Pi}, {ϕ, 0, Pi}, 
                    DisplayFunction -> Identity], 
                Table[myCylinder[{0, y -  .125, 0}, {0, y +  .125, 
                      0},  .5 Cos[y/1.75 - π/7]], {y, -2, 2,  .25}], 
                myCylinder[{0, 2.75, 0}, { .7, 3.25,  .2},  .15], 
                myCylinder[{0, 2.75, 0}, {- .7, 3.25,  .2},  .15], 
                SurfaceColor[RGBColor[ .3,  .3,  .3], White, 50], 
                mySphere[{- .8, 3.3,  .2},  .25], 
                mySphere[{ .8, 3.3,  .2},  .25], 
                SurfaceColor[mycolor, White, 5], 
                Table[myCylinder[{ .75 Cos[π/3] Sin[phi] +  .2, 
                      3.05 +  .75  Sin[π/3] Sin[phi],  .75 Cos[phi] - 
                        1}, { .75 Cos[π/3] Sin[phi +  .37] +  .2, 
                      3.05 +  .75 
                           Sin[π/3] Sin[phi +  .37],  .75 Cos[
                            phi +  .37] - 1},  .2 - phi/24], {phi,  .1, 
                    7  π/8,  .3}], 
                Table[myCylinder[{ .75 Cos[2 π/3] Sin[phi] -  .2, 
                      3.05 +  .75 
                           Sin[2 π/3] Sin[phi],  .75 Cos[phi] - 
                        1}, { .75 Cos[2 π/3] Sin[phi +  .37] -  .2, 
                      3.05 +  .75 
                           Sin[2 π/3] Sin[phi +  .37],  .75 Cos[
                            phi +  .37] - 1},  .2 - phi/24], {phi,  .1, 
                    7  π/8,  .3}]}], 
            Table[fin[0, i, 0], {i, -1.5, 1,  .4}] /. {x_?NumberQ, 
                  y_?NumberQ, z_?NumberQ} -> {(2 Cos[y/1.1]) x, 
                  y + 1, z}, 
            Table[fin[0, i, 0], {i, -2, -1,  .5}] /. {x_?NumberQ, 
                  y_?NumberQ, z_?NumberQ} -> { .5 x, y,  .5  z + x}, 
            Table[fin[0, i, 0], {i, -2, -1,  .5}] /. {x_?NumberQ, 
                  y_?NumberQ, z_?NumberQ} -> {- .5 x, 
                  y,  .5 z + x}, 
            Table[fin[0, i, 0], {i, -1.5, 1,  .4}] /. {x_?NumberQ, 
                  y_?NumberQ, 
                  z_?NumberQ} -> {-(2 Cos[y/1.1]) x, y + 1,  
                  z}} /. {i_?NumberQ, j_?NumberQ, k_?NumberQ} -> {i, j, 
              k + ( .1 +  .2  i^2) Sin[j + t]}, 
        ViewPoint -> {2, 2, 2}, SphericalRegion -> True, 
        Boxed -> False, Axes -> False, Background -> Black, 
        ImageSize -> 600, 
        PlotRange -> {{-2, 2}, {-3, 5}, {-2, 2}}, 
        DisplayFunction -> $DisplayFunction, 
        LightSources -> {{{1, 1, 1}, RGBColor[ .6,  .6,  .6]}}, 
        AmbientLight -> RGBColor[ .3,  .3,  .3]]]

The following code animates the above image to show the fins flapping while keeping the ViewPoint constant.

flapping = 
        Table[Show[{Graphics3D[{EdgeForm[], SurfaceColor[mycolor, White, 5], 
                    First@mouth, 
                    First@ParametricPlot3D[
                        Ellipsoid[ .45,  .85,  .45, {0, 2.65, 0}], {θ, 
                          0, 2  Pi}, {ϕ, 0, Pi}, 
                        DisplayFunction -> Identity], 
                    Table[myCylinder[{0, y -  .125, 0}, {0, y +  .125, 
                          0},  .5 Cos[y/1.75 - π/7]], {y, -2, 
                        2,  .25}], 
                    myCylinder[{0, 2.75, 0}, { .7, 3.25,  .2},  .15], 
                    myCylinder[{0, 2.75, 0}, {- .7, 3.25,  .2},  .15], 
                    SurfaceColor[RGBColor[ .3,  .3,  .3], White, 50], 
                    mySphere[{- .8, 3.3,  .2},  .25], 
                    mySphere[{ .8, 3.3,  .2},  .25], 
                    SurfaceColor[mycolor, White, 5], 
                    Table[myCylinder[{ .75 Cos[π/3] Sin[phi] +  .2, 
                          3.05 +  .75 
                               Sin[π/3] Sin[phi],  .75 Cos[phi] - 
                            1}, { .75 Cos[π/3] Sin[phi +  .37] +  .2, 
                          3.05 +  .75 
                               Sin[π/3] Sin[phi +  .37],  .75 Cos[
                                phi +  .37] - 1},  .2 - phi/24], {phi,  .1, 
                        7  π/8,  .3}], 
                    Table[myCylinder[{ .75 Cos[2 π/3] Sin[phi] -  .2, 
                          3.05 +  .75 
                               Sin[2 π/3] Sin[phi],  .75 Cos[phi] - 
                            1}, { .75 Cos[2 π/3] Sin[
                                phi +  .37] -  .2, 
                          3.05 +  .75 
                               Sin[2 π/3] Sin[phi +  .37],  .75 Cos[
                                phi +  .37] - 1},  .2 - phi/24], {phi,  .1, 
                        7  π/8,  .3}]}], 
                Table[fin[0, i, 0], {i, -1.5, 1,  .4}] /. {x_?NumberQ, 
                      y_?NumberQ, 
                      z_?NumberQ} -> {(2 Cos[y/1.1]) x, y + 1, z}, 
                Table[fin[0, i, 0], {i, -2, -1,  .5}] /. {x_?NumberQ, 
                      y_?NumberQ, z_?NumberQ} -> { .5 x, 
                      y,  .5  z + x}, 
                Table[fin[0, i, 0], {i, -2, -1,  .5}] /. {x_?NumberQ, 
                      y_?NumberQ, z_?NumberQ} -> {- .5 x, 
                      y,  .5 z + x}, 
                Table[fin[0, i, 0], {i, -1.5, 1,  .4}] /. {x_?NumberQ, 
                      y_?NumberQ, 
                      z_?NumberQ} -> {-(2 Cos[y/1.1]) x, 
                      y + 1,  z}} /. {i_?NumberQ, j_?NumberQ, 
                  k_?NumberQ} -> {i, j, 
                  k + ( .1 +  .2  i^2) Sin[j + t]}, 
            ViewPoint -> {2, 2, 2}, SphericalRegion -> True, 
            Boxed -> False, Axes -> False, 
            Background -> Black, ImageSize -> 600, 
            PlotRange -> {{-2, 2}, {-3, 5}, {-2, 2}}, 
            DisplayFunction -> $DisplayFunction, 
            LightSources -> {{{1, 1, 1}, RGBColor[ .6,  .6,  .6]}}, 
            AmbientLight -> RGBColor[ .3,  .3,  .3]], {t, 0, 
            2 π,  .1}];

Now, we export.

SetDirectory[
        ToFileName[("FileName" /. 
                NotebookInformation[
                  EvaluationNotebook[]])[[1]]]];

Export["anomalocaris.gif", flapping, "GIF", 
        ConversionOptions -> {"Loop" -> True}];

References

http://www.palaeos.com/Invertebrates/Arthropods/Anomalocarida/species3.html