1
$\begingroup$

I would like to illustrate a sequence of translations and rotations relative to the initial coordinate system simultaneously with multiple views using Manipulate. I discovered that there are some transformations that do not play well together with untransformed objects with Show.

Are there some settings or perhaps a better structure to make the process more robust?

I am using Mathematica 12.0 ("12.0.0 for Microsoft Windows (64-bit) (April 6, 2019)") and I have the same results on two different Windows 7 and 10 machines.

Here is the code for my toy model.

(* Create Transform Function *)
(* Unit Vectors *)
{ex, ey, ez} = UnitVector[3, #] & /@ {1, 2, 3};
(* Set up Transform Function*)
m = IdentityMatrix[4];
(* Rotation Part *)
m[[1 ;; 3, 1 ;; 3]] = 
  RotationMatrix[c, ey].EulerMatrix[{a, b, 0}, {2, 1, 2}];
(* Translation Part *)
m[[1 ;; 3, -1]] = {r Cos[-a], y, r Sin[-a]};
transform[a_, b_, c_, r_, y_] = TransformationFunction[m];
(* Create base graphics for axes and reference geo *)
axes = {Red, Arrow[{{0, 0, 0}, {#, 0, 0}}], Green, 
    Arrow[{{0, 0, 0}, {0, #, 0}}], Blue, 
    Arrow[{{0, 0, 0}, {0, 0, #}}]} &;
sphereaxes = {Dashed}~Join~axes[#]~
    Join~{White, Specularity[White, 50], Opacity[0.1], 
     Sphere[{0, 0, 0}, #]} &;
cyl = {White, Specularity[White, 50], Opacity[0.1], 
   Cylinder[{{0, 0, 0}, {0, 2, 0}}, 1]};
(* Scene objects *)
refgr = Graphics3D[axes[1/4]~Join~cyl, Boxed -> False, 
   ViewProjection -> "Orthographic"];
movgeo = sphereaxes[1/3];

The Manipulate code:

(* Create Slider Model *)
Manipulate[
 With[{
   movgeotr = 
    Graphics3D@
     GeometricTransformation[movgeo, transform[a, b, c, x, y]]},
  GraphicsGrid[{
    {Show[{refgr, movgeotr}, ViewPoint -> Back, 
      ViewVertical -> {0, 0, -1}],
     Show[{refgr, movgeotr}, ViewPoint -> {0, 0, Infinity}]},
    {Show[{refgr, movgeotr}, ViewPoint -> {-Infinity, 0, 0}, 
      ViewVertical -> {-1, 1, 0}],
     Show[{refgr, movgeotr}, 
      ViewPoint -> {Infinity, Infinity, Infinity}, 
      ViewVertical -> {0, 1, 0}]}
    }, Dividers -> Center, Frame -> All, Spacings -> Scaled[0.25], 
   ImageSize -> Medium]
  ],
 {x, 0, 1}, {y, 0, 1}, {a, 0, 360 Degree}, {b, 0, 180 Degree}, {c, 0, 
  360 Degree}]

When I execute the Manipulate expression, there are certain conditions that cause most views to be poorly displayed as shown below:

Manipulate Animation

A minimal case to produce the effect is shown below:

Graphics3D@GeometricTransformation[movgeo, transform[0, 0, 0, 0.4, 0]]
Show[{refgr, 
  Graphics3D@
   GeometricTransformation[movgeo, transform[0, 0, 0, 0.4, 0]]}, 
 ViewPoint -> {0, 0, Infinity}]

Minimal Result

The transformed object displays with Graphics3D, but will not display when combined with the untransformed object in Show. Any advice is appreciated.

$\endgroup$
  • 1
    $\begingroup$ It might be a Windows specific issue. I don't see your issue in M12 on OSX. $\endgroup$ – Carl Woll May 14 at 16:04
  • $\begingroup$ @CarlWoll Thanks for checking that out on a different system! At least the current approach should in principle work. I have also submitted a request to Wolfram to get their opinion. $\endgroup$ – Tim Laska May 14 at 16:22
1
$\begingroup$

It appears that Show is not behaving as intended on at least Windows 7 and 10 (CASE:4260146). I have found a work around that required 2 changes although I do not know how general the fix will be.

First, I found that if represented the cylinder with a RegionPlot3D or ContourPlot3D versus a Cylinder primitive, it will display over the range of parameters. ContourPlot3D performs much better, presumably because there is no volume rendering taking place.

Second, I found the isometric view (the last view) did not like the Infinity specification for the ViewPoint so I replaced them with smaller values.

The adjusted code and Manipulate results are shown below.

(* Create Transform Function *)
(* Unit Vectors *)
{ex, ey, ez} = UnitVector[3, #] & /@ {1, 2, 3};
(* Set up Transform Function*)
m = IdentityMatrix[4];
(* Rotation Part *)
m[[1 ;; 3, 1 ;; 3]] = 
  RotationMatrix[c, ey].EulerMatrix[{a, b, 0}, {2, 1, 2}];
(* Translation Part *)
m[[1 ;; 3, -1]] = {r Cos[-a], y, r Sin[-a]};
transform[a_, b_, c_, r_, y_] = TransformationFunction[m];
(* Create base graphics for axes and reference geo *)
axes = {Red, Arrow[{{0, 0, 0}, {#, 0, 0}}], Green, 
    Arrow[{{0, 0, 0}, {0, #, 0}}], Blue, 
    Arrow[{{0, 0, 0}, {0, 0, #}}]} &;
sphereaxes = {Dashed}~Join~axes[#]~
    Join~{White, Specularity[White, 50], Opacity[0.1], 
     Sphere[{0, 0, 0}, #]} &;
cyl = ContourPlot3D[x^2 + z^2 == 1, {x, -1, 1}, {y, 0, 2}, {z, -1, 1},
    Mesh -> None, 
   ContourStyle -> 
    Directive[Opacity[0.1], White, Specularity[White, 50]], 
   Boxed -> False, Axes -> False];
(* Scene objects *)
refgr = cyl;
movgeo = sphereaxes[1/3];
(* Create Slider Model *)
Manipulate[
 With[{
   movgeotr = 
    Graphics3D@
     GeometricTransformation[movgeo, transform[a, b, c, x, y]]},
  GraphicsGrid[{
    {Show[{refgr, movgeotr}, ViewPoint -> {0, Infinity, 0}, 
      ViewVertical -> {0, 0, -1}],
     Show[{refgr, movgeotr}, ViewPoint -> {0, 0, Infinity}]},
    {Show[{refgr, movgeotr}, ViewPoint -> {-Infinity, 0, 0}, 
      ViewVertical -> {-1, 1, 0}],
     Show[{refgr, movgeotr}, ViewPoint -> {5, 5, 5}, 
      ViewVertical -> {0, 1, 0}]}
    }, Dividers -> Center, Frame -> All, Spacings -> Scaled[0.25], 
   ImageSize -> Medium]
  ],
 {x, 0, 1}, {y, 0, 1}, {a, 0, 360 Degree}, {b, 0, 180 Degree}, {c, 0, 
  360 Degree}]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.