It got a bit out of hand, but here's a way to construct a ViewMatrix
pair from the triple ViewVector
, ViewAngle
, and ViewVertical
. The left figure is the Graphics3D
object using ViewVector
, ViewAngle
, and ViewVertical
and the right is the one using ViewMatrix
. If you rotate the left figure or scale it (by dragging the figure while keeping Alt depressed), the ViewMatrix
is updated automatically.
DynamicModule[{tt, pp, bb, gr, center, scale, v1, vv,
theta, phi, alpha, vert, viewAngle},
gr = {Cuboid[{-1, -1, -1}, {0, 0, 0}],
Cuboid[], {Red, Cuboid[{-1, 0, 0}, {0, 1, 1}]},
{Blue, Cuboid[{2, 0, 1}, {3, 1, 2}]}};
bb = PlotRange[Graphics3D[gr]];
scale = 1/Abs[#1 - #2] & @@@ bb;
center = Mean /@ bb;
vv = {{6, 5, 2}, Mean /@ bb};
v1 = (vv[[1]] - center);
vert = {0, 0, 1} - {0, 0, 1}.v1 v1;
viewAngle = 50 Degree;
theta[v1_] := ArcTan[v1[[3]], Norm[v1[[;; 2]]]];
phi[v1_] := If[Norm[v1[[;; 2]]] > .0001, ArcTan[v1[[1]], v1[[2]]], 0];
alpha[vert_, v1_] := ArcTan[{-Sin[phi[v1]], Cos[phi[v1]], 0}.vert,
Cross[v1/Norm[v1], {-Sin[phi[v1]], Cos[phi[v1]], 0}].vert];
tt[v1_, vert_, center_, r_] := TransformationMatrix[
RotationTransform[-alpha[vert/scale, v1], {0, 0, 1}].
RotationTransform[-theta[v1], {0, 1, 0}].
RotationTransform[-phi[v1], {0, 0, 1}].
ScalingTransform[r {1, 1, 1}].
TranslationTransform[-center]];
pp[ang_] := {{1, 0, - Tan[ang], 1}, {0, 1, - Tan[ang ], 1}, {0,
0, -Tan[ang ], 0}, {0, 0, -2 Tan[ang] , 2}};
Panel[Column[{Labeled[#,
Style["Transforming ViewVector/ViewVertical/ViewAngle to ViewMatrix",
15, FontFamily -> "Helvetica", Bold],
Top, Background -> White, Frame -> True, FrameStyle -> Gray] &@
Grid[{
{Labeled[Dynamic@
Graphics3D[{gr}, Axes -> True, AxesLabel -> {"x", "y", "z"},
ViewAngle -> Dynamic[viewAngle],
ViewVector -> Dynamic[vv, (vv = #; center = vv[[2]]; v1 = vv[[1]] - center) &],
ViewVertical -> Dynamic[vert],
ImageSize -> 270],
Style["ViewVector, ViewVertical, ViewAngle", FontFamily -> "Helvetica", Bold],
Top, Frame -> True],
Labeled[Dynamic@Graphics3D[{gr},
ViewMatrix -> {tt[v1, vert, center, Cot[viewAngle/2]/Norm[v1]], pp[viewAngle/2]},
Axes -> True, AxesLabel -> {"x", "y", "z"}, ImageSize -> 270],
Style["ViewMatrix", Bold, FontFamily -> "Helvetica"], Top,
Frame -> True]},
{Dynamic@ Labeled[N[{tt[v1, vert, center, Cot[viewAngle/2]/Norm[v1]],
pp[viewAngle/2]}] /. {a_?NumericQ :> NumberForm[a, 3]} //
MatrixForm[#, TableDirections -> Row] &,
Style["ViewMatrix", 12, FontFamily -> "Helvetica", Bold], Left], SpanFromLeft}},
Spacings -> {1, 2}],
Button["Print ViewMatrix",
Print[N[{tt[v1, vert, center, Cot[viewAngle/2]/Norm[v1]], pp[viewAngle/2]}]],
ImageSize -> 150]},
Alignment -> Left]
]
]