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$
3
  • 1
    $\begingroup$ You need #[[2]] - #[[1]] as the 3rd argument to Rotate $\endgroup$ Commented Apr 29, 2017 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
    Commented Apr 30, 2017 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$ Commented Apr 30, 2017 at 11:42

2 Answers 2

3
$\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$
3
  • $\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
    Commented Apr 29, 2017 at 20:16
  • $\begingroup$ Thanks, I have localized variables. $\endgroup$
    – webcpu
    Commented Apr 29, 2017 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
    Commented Apr 30, 2017 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 and acknowledge you have read our privacy policy.

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