10
$\begingroup$

Edit - I made the example data much smaller, so it's not so much to download.

I am trying to make animations of electronic orbitals, using functions like the ones listed here. In order to make an animation, I need for the resulting 3D image to have a stationary camera - i.e. no jumping around from frame to frame. Here are two examples that I can't get this to work on.

{model,polygons1,polygons2}=Get["https://gist.githubusercontent.com/jasondbiggs/474f13ef2680bf5afe1c/raw/3defa3ce25f3c10eeb7ab2836dbb50ce4b3d50a1/data.m"];

Graphics3D /@ {model, polygons1, polygons2}

enter image description here

We have a skeleton, and a group of polygons (stripped from a 3D contour plot). I combine them and give them the same options for ViewPoint, ViewVertical, and ViewCenter.

image1 = Graphics3D[{{Red, polygons1}, model}, 
   ViewPoint -> {0.14, 0.2, -3.4}, ViewVertical -> {0.04, 0.01, -2.0},
    Boxed -> False, ViewPoint -> {0, 0, 3.4}];
image2 =
  Graphics3D[{{Blue, polygons2}, model}, 
   ViewPoint -> {0.14, 0.2, -3.4}, ViewVertical -> {0.04, 0.01, -2.0},
    Boxed -> False, ViewPoint -> {0, 0, 3.4}];

But when I cycle through them, they are clearly shown from different vantage points,

Manipulate[Show[{image1, image2}[[image]]], {image, {1, 2}}]

enter image description here

So what am I missing? How can I make sure that every single time I create a 3D image that the view is identical? Is there another important viewing option besides those 3?

Thanks in advance.

$\endgroup$
12
  • $\begingroup$ I don't understand. Are the two image files supposed to be EXACTLY the same? The ViewXXX parms are referred to the coordinate axes, not to the image itself $\endgroup$ Commented May 16, 2014 at 22:43
  • $\begingroup$ There are more View* options: ViewVector, ViewAngle, ViewVertical, ViewPoint, ViewCenter, and ViewRange (I think the first three are the ones you need to fix). Instead of setting each of these individually, you can just set the ViewMatrix (which in turn depends on these) and you should be fine. See this question for more, especially Heike's answer: mathematica.stackexchange.com/q/3528/5 (I think this fully addresses what you want to achieve) $\endgroup$
    – rm -rf
    Commented May 16, 2014 at 22:44
  • $\begingroup$ @belisarius The two images are not exactly the same. In particular, the blue and red surfaces are different in the images. But the coordinate system is the same, the coordinates of the stick-and-ball model are the same. So I should be able to make images that have the model in exactly the same spot but the surfaces move. $\endgroup$
    – Jason B.
    Commented May 16, 2014 at 22:46
  • $\begingroup$ Ah, ok. I understand now $\endgroup$ Commented May 16, 2014 at 22:48
  • 2
    $\begingroup$ So nothing short of the complete ViewMatrix will help you? This is inconvenient with the given limitations of AbsoluteOptions. $\endgroup$
    – Yves Klett
    Commented May 20, 2014 at 19:22

2 Answers 2

3
$\begingroup$

If the issue is that internally Graphics3D sets any scaling and view based on what's in the object being displayed, how about making all objects with the same "stuff" but different colors? In other words, include all of the possible pieces but use Transparent for the color of the pieces not to be seen in a particular image.

image1 = Graphics3D[{{Red, polygons1}, {Transparent,EdgeForm[None], polygons2}, 
   model}, ViewPoint -> {0.14, 0.2, -3.4}, 
  ViewVertical -> {0.04, 0.01, -2.0}, Boxed -> False]
image2 = Graphics3D[{{Blue, polygons2}, {Transparent,EdgeForm[None], polygons1}, 
   model}, ViewPoint -> {0.14, 0.2, -3.4}, 
  ViewVertical -> {0.04, 0.01, -2.0}, Boxed -> False]

Manipulate[Show[{image1, image2}[[image]]], {image, {1, 2}}]
$\endgroup$
7
  • 3
    $\begingroup$ You could also just set the PlotRange for each image, which is effectively what you're doing by including the same data in both images. $\endgroup$
    – N.J.Evans
    Commented Feb 16, 2016 at 17:34
  • $\begingroup$ @N.J.Evans That's got to be much more efficient than what I proposed. You should write-up that answer. $\endgroup$
    – JimB
    Commented Feb 16, 2016 at 17:38
  • $\begingroup$ @N.J.Evans You're right. Actually, if you just add a given PlotRange inside the Show (in Manipulate) it fixes the problem. $\endgroup$
    – SquareOne
    Commented Feb 16, 2016 at 18:00
  • 1
    $\begingroup$ Jim, this works for 2 data sets but for hundreds it would scale poorly. For SquareOne's suggestion, maybe we could use Charting`get3Dplotrange to figure the best plot range. $\endgroup$
    – Jason B.
    Commented Feb 16, 2016 at 18:55
  • $\begingroup$ @JasonB. No disagreement here. It can even be sluggish for just 2 large data sets. $\endgroup$
    – JimB
    Commented Feb 16, 2016 at 19:09
2
$\begingroup$

Users N.J.Evans and SquareOne came up with this, but I'll post it just so the question can be answered.

I had originally made these plots using the functions here and they are essentially made via commands like

Show[ model, ListContourPlot3D[ data, options]]

where model is the 3D chemical model and options would include things like PlotRange. I had tried to be specific and give the exact same PlotRange to every molecule plot. But it would seem that the PlotRange given to ListContourPlot3D did not directly affect the PlotRange of the combined graphic created with Show. You can see this by

Charting`get3DPlotRange /@ {image1, image2}
(* {{{-277.634, 287.701}, {-170.275, 172.791}, {-135.625, 
   135.624}}, {{-276.904, 286.273}, {-170.267, 172.414}, {-115.797, 
   115.742}}} *)

So the answer to my original question, "What option, in addition to ViewPoint, ViewAngle, and ViewVertical, do I have to set to ensure that the 3D graphics viewpoint is the same?" is that you have to have the same PlotRange in the final display of the Graphics3D object.

Manipulate[
 Show[{image1, image2}[[image]], 
  PlotRange -> {{-278, 288}, {-170, 173}, {-136, 136}}], {image, {1, 
   2}}]

enter image description here

$\endgroup$
2
  • $\begingroup$ Well, obviously, since Show creates a graphic that inherits the options of the first argument (first element of first list) passed to Show and ignores the options of the subsequent graphics. Overriding options should always be passed to Show itself, not to its arguments. $\endgroup$
    – LLlAMnYP
    Commented Jul 30, 2016 at 9:05
  • $\begingroup$ @LLlAMnYP, that's correct. $\endgroup$ Commented Jul 31, 2016 at 4:11

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.