# Open pyramid flower-like by rotating its faces

I'm trying to animate a pyramid (with any base) opening its lateral faces like a flower. I found the best way to this to be the Rotate function.

The problem is, I have no clue how it works. I have read the documentation page and tried some simple examples but every time the rotation I end up with seems completely random to me.

The pyramid has its center in the origin and it's built with the following function:

    myPyramid[edges_, open_] := (
points = Map[Append[#, 0] &, CirclePoints[edges]];
apex = {0, 0, 2};
base = Polygon[points];
points = Append[points, points[[1]]];
faces = Partition[points, 2, 1];
{Map[Rotate[ Polygon[Join[#, {apex}]],
open Degree, #[[2]] , #[[1]]] &, faces], base}
)


Since I need to rotate a Polygon around its base I though the function I was looking for was

Rotate[g,θ,w,p] rotates around the 3D vector w anchored at p.

However the result is not what I was looking for; the faces detach from the base and start rotating around a vertex.

    Manipulate[Graphics3D[myPyramid[5, x],
Axes -> True, PlotRange -> {{-2, 2}, {-2, 2}, {-1, 3}}], {x, 0, 90}]


Can anyone please explain to me how does Rotate works in 3D and/or how to rotate said faces the way I want?

• You need #[[2]] - #[[1]] as the 3rd argument to Rotate – Simon Woods Apr 29 '17 at 9:26
• Thanks, it works exactly as I intended it. Can you explain me why? I can't understand exactly why I have to subtract the vectors of the edge I want it to rotate around – Maldus Apr 30 '17 at 8:59
• You have specified each edge by the points at either end {p, q}. The vector you want to rotate around runs from p to q, and that vector is given by q - p. – Simon Woods Apr 30 '17 at 11:42

To rotate, it's better to remove box lines and axes.

If you wan to animate it, you can replace Manipulate with Animate in the code.

In:

myPyramid[edges_, open_] := Module[{points, apex, base, faces, rotate},
points = Map[Append[#, 0] &, CirclePoints[edges]];
apex = {0, 0, 2};
base = Polygon[points];
points = Append[points, points[[1]]];
faces = Partition[points, 2, 1];
rotate =
Rotate[Polygon[Join[#, {apex}]], open Degree, #[[2]], #[[1]]] &;
{faces // Map[rotate], base}]

Manipulate[
Graphics3D[myPyramid[5, x], PlotRange -> {{-3, 3}, {-3, 3}, {0, 3}},
SphericalRegion -> True,
Boxed -> False,
Axes -> False,
ImageSize -> Large,
ViewPoint -> RotationTransform[x 90/(2 Pi), {0, 0, 1}][{3, 0, 3}]],
{x, 0, 90}]


Out:

• A good answer, but it would be better were you to localize variables in myPyramid; i.e., myPyramid[edges_, open_] := Module[{points, apex, base, faces}, ... ]. I can see that you just copied the OP's function, but I am recommending to take the opportunity to show the OP how to improve it. – m_goldberg Apr 29 '17 at 20:16
• Thanks, I have localized variables. – UnchartedWorks Apr 29 '17 at 20:48
• That is not what I wanted. I wanted the lateral faces to open up rotating around their bases, not to add a viewpoint rotation. Simon's comment answered me, but I still want to understand how/why it works. +1 for the Module usage example, though, it was helpful. – Maldus Apr 30 '17 at 9:04

As per Simon's comment, everything I needed to do was to use the vector #[[2]] -#[[1]] as third argument. My final result is:

myPyramid[edges_,
open_] := (points = Map[Append[#, 0] &, CirclePoints[edges]];
apex = {0, 0, 2};
base = Polygon[points];
points = Append[points, points[[1]]];
faces = Partition[points, 2, 1];
{Map[Rotate[Polygon[Join[#, {apex}]],
open Degree, #[[2]] - #[[1]], #[[1]]] &, faces], base})

Manipulate[
Graphics3D[myPyramid[faces, x], Axes -> True,
PlotRange -> {{-3, 3}, {-3, 3}, {-1, 3}}], {faces,
Range[3, 12]}, {x, 0, 110} ]


Which leads to the animation I wanted:

As Simon said,

You have specified each edge by the points at either end {p, q}. The vector you want to rotate around runs from p to q, and that vector is given by q - p