3

I posted at this post before, but I still could not solve the following problem completely. As an example:

{pA, pB, pC, pD} = {{0, 0, Sqrt[61/3]}, {Sqrt[7], 4*Sqrt[2/3], 0}, {0, -5*Sqrt[2/3], 0}, {-Sqrt[71], 4*Sqrt[2/3], 0}};
axis={1,0,0};pt={0,1,0};
plotPolygon[{a_, b_, c_}] := {Opacity[.4], Polygon[{a, b, c}]};
graph=Graphics3D[{plotPolygon[{pA, pB, pC}], plotPolygon[{pA, pB, pD}], 
            plotPolygon[{pB, pC, pD}], plotPolygon[{pA, pC, pD}]}, 
            Axes -> True, AxesOrigin->pt];
Animate[graph/.gg : Graphics3D[___] :> Rotate[gg, theta, axis], {theta, 0., 2.*Pi}]

enter image description here

I want to rotate along an axis axis={1,0,0} which passes the point pt={0,1,0}. But I don't know how to specify the point information. Also the rotation animation seems very chaotic in the sense that I would expect at least one point (in this case, the origin?) is not rotating.

Community
  • 1
  • 1
Qiang Li
  • 10,593
  • 21
  • 77
  • 148

1 Answers1

4

You need to first change the origin of vertices of your polygon, rotate, and translate back. You can do this by hand

(RotationMatrix[theta,axis].(#-pt) + pt)& /@ {pA, pB, pC, pD}

Or, you can combine the transformations using Composition

Composition[
 AffineTransform[{RotationMatrix[theta,axis],pt}],TranslationTransform[-pt]
] /@ {pA, pB, pC, pD}

Or, you can take the previous composition and apply it directly to your Graphics object

GeometricTransformation[ <graphics>, Composition[ ... ]]

This documentation gives a thorough list of what can be done.

Edit: Here's a working animation script

Animate[
  graph /. Graphics3D[prims__, opts : OptionsPattern[]] :> 
    Graphics3D[
      GeometricTransformation[prims,
        Composition[
          AffineTransform[{RotationMatrix[theta, axis], pt}],
          TranslationTransform[-pt]
        ]
      ],
      opts
    ], 
  {theta, 0., 2.*Pi}
]

There's a couple of things to note here. First, GeometricTransformation only appears to work on the primitives themselves, so I had to split out the primitives from the options in Graphics3D via the rule Graphics3D[prims__, opts : OptionsPattern[]]. Also, the transformation itself needs to be within Animate to use the local version of theta.

rcollyer
  • 10,475
  • 4
  • 48
  • 75
  • could you make the example I gave work? I tried, but still don't know how. thanks a lot. – Qiang Li Mar 04 '11 at 21:26
  • One thing to add, `AffineTransform` does the translate back for us after the rotation, so I used it instead of doing it in 3 steps. – rcollyer Mar 05 '11 at 18:35