[Edit notice: Updated to allow the setting of the vertical direction of the plot and to fix an error.]
Here is a slight generalization of my answer to Isometric 3d Plot. To get an isometric view, we need to construct a ViewMatrix
that will rotate a vector of the form {±1, ±1, ±1}
to {0, 0, 1}
and project orthogonally onto the first two coordinates.
ClearAll[isometricView];
isometricView[
g_Graphics3D, (* needed only for PlotRange *)
v_ /; Equal @@ Abs[N@v] && 1. + v[[1]] != 1., (* view point {±1, ±1, ±1} *)
vert_: {0, 0, 1}] := (* like ViewVertical; default: z-axis *)
{TransformationMatrix[
RescalingTransform[
EuclideanDistance @@
Transpose[Charting`get3DPlotRange@ g] {{-1/2, 1/2}, {-1/2, 1/2}, {-1/2, 1/2}}].
RotationTransform[{-v, {0, 0, 1}}].
RotationTransform[{vert - Projection[vert, v], {0, 0, 1} - Projection[{0, 0, 1}, v]}].
RotationTransform[Mod[ArcTan @@ Most[v], Pi], v].
TranslationTransform[-Mean /@ (Charting`get3DPlotRange@ g)]],
{{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}};
foo = Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}]];
Show[foo, ViewMatrix -> isometricView[foo, {1, 1, 1}, {0, 0, 1}],
ImagePadding -> 20, Axes -> True, AxesLabel -> {x, y, z}]
Show[foo, ViewMatrix -> isometricView[foo, {-1, 1, 1}, {1, 1, 0}],
ImagePadding -> 20, Axes -> True, AxesLabel -> {x, y, z}]
All combinations of viewpoints and vertical axes:
Notes:
Getting an accurate plot range that includes the padding is important to computing the correct view matrix. There are alternatives to the undocumented internal function Charting`get3DPlotRange
.
Alexey Popkov has a method here:
How to get the real PlotRange using AbsoluteOptions?
I used PlotRange /. AbsolutOptions[g, PlotRange]
and multiplied by 1.02
(I don't recall why not something like 1.04
) to approximate the padding in my answer to Isometric 3d Plot.
My go-to resource for understanding ViewMatrix
has been especially Heike's answer to Extract values for ViewMatrix from a Graphics3D.
This update is in response to Yves' comment. Working with the axes made me realize that the coordinate system is flipped (from "right-handed" to "left-handed). Hence I changed the projection from IdentityMatrix[4]
to one that flips the x & y coordinates.
It might be a good idea to Deploy
the graphics to prevent rotation by the mouse. When the graphics are rotated, the front end resets the ViewMatrix
in a rather ugly way.