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.
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityI 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.
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]
}}]
]
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.
$\endgroup$
– Mr.Wizard
Aug 7 '13 at 13:43
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