7
$\begingroup$

I am working on building a molecule viewer in Mathematica and am running in to problems with controlling rotation of the molecule (which is rendered as a Graphics3D object). I apologize in advance for the lengthy code used to build the sample molecule; however the form of the graphics object is representative of real molecule objects generated by my molecule viewer package. I've moved this code to the end of the question so it hopefully does not distract from the real question.

Ultimately, I would like to be able to use the mouse or controllers to adjust the orientation of a 3D object. Then I would like to be able to rotate that object around the vertical axis. The animated gif below demonstrates the rotation:

rotating molecule

I have started from the following point:

Manipulate[
 Graphics3D[{
   Specularity[GrayLevel[1], 100], gr
   },
  Boxed -> False,
  Lighting -> "Neutral",
  SphericalRegion -> True, Background -> Black, 
  ViewVertical -> {Cos[a], 0, Sin[a]}], {a, 0, 4 Pi}]

which demonstrates two problems:

  1. Clearly, the rotation is out of the viewing plane, and unless I've missed it, no permutation of the ViewVertical values gives me the desired rotation axis.
  2. When the graphic is altered using the mouse, changing the slider no longer changes the graphic.

Next, I tried using ViewVector. I thought about being smart (no claims that I actually was) and noticed:

ParametricPlot3D[{Cos[a], Sin[a], 1}, {a, 0, 4 Pi}]

should give me the appropriate rotation:

rotation plot

Using

Manipulate[
 Graphics3D[{
   Specularity[GrayLevel[1], 100], gr
   },
  Boxed -> False,
  Lighting -> "Neutral",
  SphericalRegion -> True, Background -> Black, 
  ViewVector -> 1000 {Cos[a], Sin[a], 1}], {a, 0, 4 Pi}]

comes close to the rotation I'm looking for and it doesn't seem to be affected by problem (2) above. However when I do move the graphic with the mouse, the rotation axis changes in a way that makes no sense to me.

I suspect my code needs to capture the current ViewVector and perform a rotation based on that information; however I'm having a hard enough time grasping the various View* options in Graphics3D that I can't begin to formulate that level of dynamic interactivity.

Update

Since posting this question and reviewing this reference which was provided in the comments I am able to rotate the camera which provides a decent means to view the molecule. As alluded to in one of the possible answers, rotating the molecule as opposed to rotating the viewpoint may be a better approach. (I put this code here only because I was stumped by the conditional that is needed for ViewVertical, preventing the molecule from jumping.)

Manipulate[ 
 Graphics3D[{Specularity[GrayLevel[1], 100], gr}, Boxed -> False, 
  Lighting -> "Neutral",
  ViewPoint -> 2 {Sin[a] Sin[b], Cos[a] Sin[b], Cos[b]}, 
  ViewCenter -> Automatic, 
  ViewVertical -> If[b > 0, {0, 0, 1}, {0, 0, -1}], ViewRange -> All, 
  ViewAngle -> All, SphericalRegion -> True, 
  Background -> Black], {{a, 0}, 0, 4 Pi}, {{b, .01}, -Pi, Pi}]

The molecule

{and a caveat for all the chemists out there - this is not a real molecule}

gr = GraphicsGroup[{EdgeForm[None], 
  GraphicsComplex[{{-7.53741, 11.3862, 4.91147}, {146.654, 5.10132, 
     2.65685}, {200.92, 7.38748, 138.895}, {199.898, 
     116.382, -68.4703}, {188.424, -110.427, -58.9037}}, {{{RGBColor[
       0.4, 0.4, 0.4], Sphere[1, 34]}, {RGBColor[0.4, 0.4, 0.4], 
      Sphere[2, 34]}, {RGBColor[0.29, 0.44, 0.89], 
      Sphere[3, 32]}, {RGBColor[0.8, 0.2, 0.2], 
      Sphere[4, 31]}, {RGBColor[0.58, 0.86, 0.41], Sphere[5, 30]}}}], 
  GraphicsComplex[{{-7.53741, 11.3862, 4.91147}, {146.654, 5.10132, 
     2.65685}, {146.654, 5.10132, 2.65685}, {146.654, 5.10132, 
     2.65685}, {69.5583, 8.24374, 3.78416}, {173.787, 6.2444, 
     70.7759}, {173.276, 
     60.7416, -32.9067}, {167.539, -52.6626, -28.1234}}, {{RGBColor[
      0.4, 0.4, 
      0.4], {GeometricTransformation[
       Cylinder[{1, 5}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0.0418653, 
         5.9645, -13.7631}}], 
      GeometricTransformation[
       Cylinder[{1, 5}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 
          1.}}, {-0.0418653, -5.9645, 13.7631}}]}, 
     RGBColor[0.4, 0.4, 
      0.4], {GeometricTransformation[
       Cylinder[{2, 6}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0., 0., 
         0.}}]}, RGBColor[0.4, 0.4, 
      0.4], {GeometricTransformation[
       Cylinder[{3, 7}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0., 0., 
         0.}}]}, RGBColor[0.4, 0.4, 
      0.4], {GeometricTransformation[
       Cylinder[{4, 8}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0., 0., 
         0.}}]}}}], 
  GraphicsComplex[{{146.654, 5.10132, 2.65685}, {200.92, 7.38748, 
     138.895}, {199.898, 
     116.382, -68.4703}, {188.424, -110.427, -58.9037}, {69.5583, 
     8.24374, 3.78416}, {173.787, 6.2444, 70.7759}, {173.276, 
     60.7416, -32.9067}, {167.539, -52.6626, -28.1234}}, {{RGBColor[
      0.4, 0.4, 
      0.4], {GeometricTransformation[
       Cylinder[{1, 5}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 
          1.}}, {-0.0418653, -5.9645, 13.7631}}], 
      GeometricTransformation[
       Cylinder[{1, 5}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0.0418653, 
         5.9645, -13.7631}}]}, 
     RGBColor[0.29, 0.44, 
      0.89], {GeometricTransformation[
       Cylinder[{2, 6}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0., 0., 
         0.}}]}, RGBColor[0.8, 0.2, 
      0.2], {GeometricTransformation[
       Cylinder[{3, 7}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0., 0., 
         0.}}]}, RGBColor[0.58, 0.86, 
      0.41], {GeometricTransformation[
       Cylinder[{4, 8}, 
        10], {{{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}}, {0., 0., 
         0.}}]}}}], Null, Null}]
$\endgroup$
4
  • $\begingroup$ "a caveat for all the chemists out there - this is not a real molecule" - you could've used bromochlorofluoromethane, but sure, let's go with that. ;) $\endgroup$ Jun 9, 2013 at 17:04
  • $\begingroup$ Careful with five bonds on carbon. $\endgroup$ Jun 9, 2013 at 17:19
  • 2
    $\begingroup$ This question might be worth of reference. $\endgroup$
    – Silvia
    Jun 9, 2013 at 19:00
  • 1
    $\begingroup$ Also related: Using Chemical Data to make molecule graphics $\endgroup$
    – Jens
    Jun 9, 2013 at 19:23

1 Answer 1

5
$\begingroup$

By using ViewVector you are rotating the point-of-view about the object, not the object itself. While these are similar, it might be easier to understand what's happening by rotating the object. This can be done:

rotAbout={0, 0, 1}; 
Manipulate[rot = RotationMatrix[a, rotAbout]; 
    Graphics3D[{Specularity[GrayLevel[1], 100], 
       GeometricTransformation[gr, rot]}, Boxed -> False, 
       Lighting -> "Neutral", SphericalRegion -> True, Background -> Black], 
{a, 0, 2 Pi}]

In this version, rot is a rotation matrix and a is the angle of rotation. You can change the vector that the object is rotated about by changing rotAbout. You could make this vector dynamic by placing it within the Manipulate and changing its entries with sliders. You can still rotate the molecule with the mouse.

enter image description here

$\endgroup$
1
  • $\begingroup$ If I set ViewPoint->{0,0,2} then I get the desired rotation with rotAbout = {0,0,1}. Same is true for {{0,2,0},{0,0,1}} and {{2,0,0},{0,0,1}}. The relationship between ViewPoint and rotAbout is not obvious to me, however. $\endgroup$ Jun 10, 2013 at 21:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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