# How to create a simple cross eyed 3d plot

I wanted to create a stereoscopic view of my threedimensional plots, so I can interpret them better.

The basic things, one would need, are two plot windows which are somehow connected to each other and modify the camera position of the second plot.

I got my inspiration from Yu-Sung Chang in his answer to a question about Mathematica's viewmatrix.

The basic idea is now, to combine the two plots and simply rotate the viewpoint of the second plot around the vertical axis by a certain angle to get a satisfying result.

So at first, we create the plot with the four view-parameters as argument.

myplot[point_,angle_,vertical_,center_]:=Graphics3D[{
(*Objects*)
EdgeForm[],Specularity[White,20],FaceForm[Red],Sphere[{-0.2,-0.1,-0.3},.2],FaceForm[Blue],Cylinder[{{0.,0.3,-.5},{0.,0.3,0.}},.1],FaceForm[Green],Cone[{{0.2,0.,-0.5},{0.2,0.,-0.1}},.2]},

Boxed->True,
Lighting->"Neutral",
ImageSize->300,
RotationAction->"Clip",

(*View control*)
ViewPoint->point,
ViewAngle->angle,
ViewVertical->vertical,
ViewCenter->center]


The next step is the connection of this plot for both eyes:

DynamicModule[
{point={1.3,-2.4,2},angle=N[35 Degree],vertical={0,0,1},center=Automatic},
Grid[{{
Framed[
myplot[Dynamic[point],Dynamic[angle],Dynamic[vertical],Dynamic[center]],
FrameStyle->LightGray],

(*The second object*)
Framed[
myplot[Dynamic[RotationMatrix[-5\[Degree],vertical].point],Dynamic[angle],Dynamic[vertical],Dynamic[center]],
FrameStyle->LightGray]
}}]
]


The result can be easily viewed crosseyed and it is possible to rotate this view with the standard controls of the left plot. Using the right plot to change the camera position doesn't work as expected.

• Okay, that's pretty darn cool. Why didn't I think of this? :^) +2 Aug 7, 2013 at 11:35
• -1 I feel discriminated for not being able to cross my eyes without focusing on my finger. (kidding)
– Rojo
Aug 7, 2013 at 17:31
• @Rojo Kidding about the -1 or kidding about not being able to cross your eyes? (I'm genuinely curious.) Aug 7, 2013 at 21:03
• @Mr.Wizard just about the -1
– Rojo
Aug 9, 2013 at 0:34
• +1 I guess the next mission would be tracing the eyeballs and accordingly blurring the portions which are away from the current focus plane! Aug 15, 2013 at 7:45

Here's a function for application to an arbitrary Graphics3D object:

Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -2, 2}] //
stereo3D[ImageSize -> 200, Axes -> False]


Syntax is either gr // stereo3D[options] or simply gr // stereo3D.

Code:

stereo3D[graphics_Graphics3D] := stereo3D[][graphics]
stereo3D[opts : OptionsPattern[Show]][graphics_Graphics3D] :=
DynamicModule[{
myplot,
point = {1.3, -2.4, 2},
angle = 35 °,
vertical = {0, 0, 1},
center = Automatic
},
myplot[pt_] :=
Framed[
Show[graphics, opts,
ViewPoint    -> pt,
ViewAngle    -> Dynamic[angle],
ViewVertical -> Dynamic[vertical],
ViewCenter   -> Dynamic[center]],
FrameStyle -> LightGray];
Grid[{{
myplot[point // Dynamic],
myplot[RotationMatrix[-5 °, vertical].point // Dynamic]
}}]
]

• Very nice extension. This way, we can handle it much easier. Aug 7, 2013 at 12:13
• @Stefan Thanks, I'm glad you approve. Aug 7, 2013 at 12:26
• @Pato I wanted to be able to use either gr // stereo3D or gr // stereo3D[(*options*)]. To do this I convert an explicit appearance of the first form into the second; it is equivalent to gr // stereo3D[]. In all of these examples x // f is equivalent to f[x], but to me more logical for a post-processing function. Aug 7, 2013 at 13:43
• May I remark that rotating the scene is not entirely equivalent to a translation of the viewpoints? Aug 7, 2013 at 21:23
• @stefan I have no problem with focussing on the center of the object (note the phrase "not entirely" in my remark), and I agree that this may be done by rotating the scene, but it doesn't take into account that some parts of the scene are closer to one eye than the other and therefore have a different projection. Imagine a small stick of 1 cm height placed vertically 6.5 cm in front of your right eye (which is 6.5 cm to the right of your left eye). The stick subtends atan(1/6.5) rads of visual angle in the right eye, but subtends only atan(1/(sqr(2)6.5)) in the left eye, a whole lot less. Aug 8, 2013 at 14:07

I've been working on this problem on Wolfram Community http://community.wolfram.com/groups/-/m/t/788811. Posting my solution here for future searchers.

stereo[expr_] :=
DynamicModule[{vp = {1.3, -2.4, 2.0}, vv = {0., 0., 2.0}, plot},
plot = expr;
GraphicsRow[{Show[plot, ViewPoint -> Dynamic[vp + {.4, 0, 0}, None],
ViewVertical -> Dynamic[vv, None], RotationAction -> "Clip"],
Show[plot, ViewPoint -> Dynamic[vp, Temporary],
ViewVertical -> Dynamic[vv, Temporary],
RotationAction -> "Clip"]}, ImageSize -> 600]]


The right-hand image is interactive; the left-hand one does not react to the mouse. When the mouse button is released after rotating the right-hand image, the left-hand image is drawn. I added RotationAction -> "Clip" because the image jumps slightly after adjustment.

By appending //stereo to a Graphics3D expression (which includes any *Plot3D` function), the stereogram is generated instead of the flat image.

Eric

• It is a shame late answers like this don't get the recognition they deserve. A belated +1. Mar 8, 2017 at 21:21