2
$\begingroup$

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}]

my opened pyramid

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

$\endgroup$
  • 1
    $\begingroup$ You need #[[2]] - #[[1]] as the 3rd argument to Rotate $\endgroup$ – Simon Woods Apr 29 '17 at 9:26
  • $\begingroup$ 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 $\endgroup$ – Maldus Apr 30 '17 at 8:59
  • $\begingroup$ 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. $\endgroup$ – Simon Woods Apr 30 '17 at 11:42
2
$\begingroup$

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: enter image description here

$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – m_goldberg Apr 29 '17 at 20:16
  • $\begingroup$ Thanks, I have localized variables. $\endgroup$ – UnchartedWorks Apr 29 '17 at 20:48
  • $\begingroup$ 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. $\endgroup$ – Maldus Apr 30 '17 at 9:04
1
$\begingroup$

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:

Flower pyramid

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.