5
$\begingroup$

Preamble

In this post from several years ago: , it has been suggested that a "Globe" method is available for RotationControl.

Graphics3D[Cone[], Method -> {"RotationControl" -> "Globe"}]

That option doesn't seem to be documented anymore, although no error is reported on its use. Graphics3D docs still have a method RotationalControl" -> "ArcBall" (no idea what it is)

Another post shows how to use manipulate to stabilize the rotation.

Task

I want to stabilize rotation of a globe or other 3D objects while viewing preferably without using any automation or manipulate. First I try it on a simpler example with two 3D shapes and it seems to have ignored the `RotationControl`. Assume that these objects are sitting on a turntable and I want to rotate the turntable. No other movement is allowed. Perhaps my usage of the command is not correct.
Graphics3D[{
  Glow[Green],
  Cuboid[{0, 0, 0}],
  Glow[Red],
  Cone[]
  },
 Boxed -> False,
 RotationAction -> "Clip",
 Method -> {"RotationControl", "Globe"},
 ImageSize -> 300,
 ImagePadding -> 30,
 ImageMargins -> 40,
 ViewPoint -> {Pi, Pi/2, 2}
 ]

Code for the globe This code has adapted to work with Mma12.2 from a older post.

globe = SphericalPlot3D[1, {u, 0, Pi}, {v, 0, 2 Pi},
  PlotPoints -> 50,
  MaxRecursion -> 0,
  Mesh -> True,
  TextureCoordinateFunction -> ({#5, 1 - #4} &),
  Boxed -> False,
  Method -> {"RotationControl", "Globe"},
  Axes -> False,
  PlotStyle -> Directive[
    Texture[
     (*Import["C:\\map.png"]],*)
     Import["https://i.sstatic.net/5JpK4.jpg"]],
    Specularity[White, 1000],
    ],
  Lighting -> "Neutral"
  ]

enter image description here

Question

While plotting Graphics3D or other 3D plots, is there a way to stabilize/force rotation of an object along latitudes and/or longitudes or other axes? What method(s) and/or option(s) are available for this purpose with such commands?

Thanks for reading.

======= First edit to include the info in Domen's answer ======

I should have pasted the code and searched harder. I went searching in the SphericalPlot pages. Notice the two cursor modes on a Graphics3D output. At the edges the cursor is circular and near the center it is elliptical arrows. Spherical cursor is more restrictive in the movements that it allows.

enter image description here

SphericalRegion

Screen capture from docs shows that it is not working as stated. But I am not sure if there are more options that go with it.

enter image description here

RotationControl

Using an example from the docs. I would say the globe is slightly better stabilized and the spherical cursor has gone away on all these modes, but still plot can be moved in arbitrary ways. (Code is included below if reqd)

enter image description here

Manipulate[Plot3D[Sin[x y], {x, 0, 2 \[Pi]}, {y, 0, 2 \[Pi]},
  Method -> {"RotationControl" -> method}],
 {
  {method, "Globe", "Rotation method:"},
  {"Globe", "ArcBall", "TrackBall"}}
 ]

What I am seeking through the question above is options so that the globe can move as a "physical globe" along one axis or graphics items could seem to rotate on a turntable. Once again, I would like to thank Domen for his reply.

$\endgroup$

1 Answer 1

5
$\begingroup$

I have not been able to found any in-built way to lock the rotation of 3D graphics around one axis, so we will have to build our own solution. Let's use EventHandler to catch the movements of mouse, and then dynamically change the point of view via ViewVector and ViewVertical. We will use the natural tilt of the Earth, i.e. $23.4^\circ$.

To make the rotation more realistic, we will use the component of the mouse movement parallel to the equator. Rotation speed can be tuned with the parameter rotationSpeed, however, some additional calibration is needed if you want to make the globe rotate exactly together with the cursor. And to make everything more funky, let's use 🌍 as a mouse cursor (you can also use "LinkHand" or any other cursor you prefer).

(* Axis tilt relative to the z-axis *)
tilt = 23.4 Degree;
(* Rotation speed *) 
rotationSpeed= 3;
(* Camera distance from the center *)
viewDistance = 3;

axis = {0, -Sin[tilt], 1};
equator = {Cos[-tilt], Sin[-tilt]};
DynamicModule[{vp = 
   RotationTransform[0, {0, 0, 1}]@{viewDistance, 0, 0}, 
  vv = RotationTransform[0, {0, 0, 1}]@axis, click = {0, 0}, 
  lastPhi = 0, phi = 0}, EventHandler[
  MouseAppearance[
   SphericalPlot3D[1, {u, 0, Pi}, {v, 0, 2 Pi}, PlotPoints -> 50, 
    MaxRecursion -> 0, TextureCoordinateFunction -> ({#5, 1 - #4} &), 
    Boxed -> False, Method -> None, Axes -> False, 
    SphericalRegion -> Sphere[{0, 0, 0}, 1.2], Mesh -> True, 
    ViewPoint -> Dynamic[vp], ViewVertical -> Dynamic[vv], 
    PlotStyle -> 
     Directive[Texture[Import["https://i.sstatic.net/5JpK4.jpg"]], 
      Specularity[White, 1000]], Lighting -> "Neutral"], 
   Graphics[Style[Text@"\|01f30d ", 40]]],
  {
   "MouseDown" :> (click = MousePosition["Graphics"]),
   "MouseDragged" :> (
     phi = 
      rotationSpeed*(equator . (click - MousePosition["Graphics"]));
     rot = RotationTransform[lastPhi + phi, {0, 0, 1}];
     vp = rot[{viewDistance, 0, 0}] ;
     vv = rot[axis]),
   "MouseUp" :> (lastPhi = lastPhi + phi)
   }]]

Globe

Old Answer

I misunderstood initially what the question is really about, so I have provided a new answer above.

Firstly, the option is actually documented under Graphics3D (Options > Method > RotationControl). Secondly, you have a bug in your code: comma instead of an arrow in "RotationControl" -> "Globe". Thirdly, use "RotationMode" -> "SphericalRegion" to stabilize rotation.

globe = SphericalPlot3D[1, {u, 0, Pi}, {v, 0, 2 Pi}, PlotPoints -> 50,
   MaxRecursion -> 0, Mesh -> True, 
  TextureCoordinateFunction -> ({#5, 1 - #4} &), Boxed -> False, 
  Method -> {"RotationControl" -> "Globe", 
    "RotationMode" -> "SphericalRegion"}, Axes -> False, 
  PlotStyle -> 
   Directive[Texture[Import["https://i.sstatic.net/5JpK4.jpg"]], 
    Specularity[White, 1000]], Lighting -> "Neutral"]

Rotation

$\endgroup$
4
  • $\begingroup$ Domen, can you, please, clarify how one can lock the axis of rotation to a set value, i.e., as if this were an actual globe being rotated? $\endgroup$ Commented Aug 30, 2021 at 17:32
  • $\begingroup$ Domen Thanks. I will be editing my question to include the information you have indicated. I should have copied and pasted the code correctly in the first place instead of typing it in and making a mistake. The globe is slightly better stabilized but as your animation shows, it can move anywhere. (as per CATrevillian's comment above). Wait for my edit please. $\endgroup$
    – Syed
    Commented Aug 30, 2021 at 17:41
  • $\begingroup$ @Syed, I have updated my answer. My code provides you with rotation about one fixed axis. Furthermore, it could be expanded in a way to allow rotation about the vertical axis (i.e. as if we would rotate the table below the globe) by, for example, dragging the white space below the globe. $\endgroup$
    – Domen
    Commented Aug 30, 2021 at 21:21
  • 1
    $\begingroup$ @Domen, many thanks for your time and for sharing your knowledge. I think in the presence of no built-in solutions, this is a good solution. I will put some other thoughts (in a few days) as a last edit on the question. $\endgroup$
    – Syed
    Commented Aug 31, 2021 at 7:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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