# How can I make sure that 3D plots have the exact same orientation and viewpoint?

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}


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


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?

-
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 – Dr. belisarius May 16 '14 at 22:43
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) – R. M. May 16 '14 at 22:44
@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. – JasonB May 16 '14 at 22:46
Ah, ok. I understand now – Dr. belisarius May 16 '14 at 22:48
So nothing short of the complete ViewMatrix will help you? This is inconvenient with the given limitations of AbsoluteOptions. – Yves Klett May 20 '14 at 19:22

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

-
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. – N.J.Evans Feb 16 at 17:34
@N.J.Evans That's got to be much more efficient than what I proposed. You should write-up that answer. – Jim Baldwin Feb 16 at 17:38
@N.J.Evans You're right. Actually, if you just add a given PlotRange inside the Show (in Manipulate) it fixes the problem. – SquareOne Feb 16 at 18:00
Jim, this works for 2 data sets but for hundreds it would scale poorly. For SquareOne's suggestion, maybe we could use Chartingget3Dplotrange to figure the best plot range. – JasonB Feb 16 at 18:55
@JasonB. No disagreement here. It can even be sluggish for just 2 large data sets. – Jim Baldwin Feb 16 at 19:09

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

Chartingget3DPlotRange /@ {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}}]


-