Function Repository Resource:

Locator3D

Source Notebook

Interactively manipulate positions and rotations in 3D

Contributed by: Lukas Lang

ResourceFunction["Locator3D"][{x,y,z}]

represents a locator object at position {x,y,z} in a 3D graphic.

ResourceFunction["Locator3D"][Dynamic[pos]]

takes the position to be the dynamically updated current value of pos, with this value being reset if the locator object is moved.

ResourceFunction["Locator3D"][{pos,rot}]

represents a locator object at position pos and rotation represented by the rotation matrix rot.

ResourceFunction["Locator3D"][{pos,Dynamic[rot]}]

takes the rotation matrix to be the dynamically updated current value of rot, with this value being reset if the locator object is rotated.

ResourceFunction["Locator3D"][,prim]

displays the graphics primitive prim as the locator object.

Details and Options

ResourceFunction["Locator3D"] is a 3D version of Locator.
ResourceFunction["Locator3D"][,Automatic] uses the default sphere appearance for the locator object when no rotation is allowed, and a cube if rotation is allowed.
ResourceFunction["Locator3D"][Dynamic[{x,y,z}]] will reset the values of x, y and z when the locator object is moved; ResourceFunction["Locator3D"][{x,y,z}] will not.
The following options can be given:
ImageSizeScaled[0.05]the size of the displayed locator object
"GuideDirections"Automaticthe directions along which the guides point
"ShowGuides"Truewhether to show guide lines and planes
"AllowedActions"Automaticwhich manipulation actions to allow
"ModifierKeys"{None,"ShiftKey",”OptionKey"}the modifier keys for the different allowed actions
"RotateGuides"Falsewhether the guide directions should be affected by the rotation matrix
ResourceFunction["Locator3D"][] is equivalent to ResourceFunction["Locator3D"][{0,0,0}].
The option ImageSize accepts the following settings:
Scaled[s]scaled size s
ssize s in graphics coordinates
The setting for ImageSize specifies the radius of the main locator sphere, with the other parts sized accordingly.
When using scaled sizes, the hit detection does not always work properly in versions 12.3 and lower. Use absolute sizing specifications instead if you are having issues selecting the arrows.
The default setting "GuideDirections"Automatic effectively corresponds to guides along the three cardinal directions.
The option "GuideDirections" accepts an arbitrary number of guide directions.
Using "GuideDirections"{dir1,dir2,}, the guide directions are dynamically updated while moving the locator.
The option "AllowedActions" accepts the following settings:
Automaticautomatically choose the allowed actions
Allallow all actions
"MoveAlong"move locator along guide directions
"MovePerpendicular"move locator perpendicular to guide direction
"Rotate"rotate locator around guide directions
{act1,act2,}list of several allowed actions
The default setting "AllowedActions"Automatic effectively always allows "MoveAlong". With "GuideDirections"Automatic, "MovePerpendicular" is also allowed. Finally, "Rotate" is enabled when an explicit rotation matrix is specified.
The option "ModifierKeys" controls how the different actions can be accessed. A list of modifier keys is expected, with the first key corresponding to the first action, etc.
In "ModifierKeys"{mod1,mod2,}, the individual modi can be any of the following:
Noneno modifier key necessary
"string"any of the strings supported by CurrentValue
"string1"&&"string2"||…logical predications of different string specifications
The default setting "ModifierKeys"{None,"ShiftKey","OptionKey"} specifies that the first allowed action should require no modifier key, the second one the -key, and the third one the -key (Windows/Linux)/the -key (macOS).
ResourceFunction["Locator3D"] supports Dynamic[,{fstart,}] type dynamic arguments to control the set/reset behavior of the position and rotation variables.
When using positions of the form Dynamic[,{fstart,}], the functions are supplied with the index of the currently active direction as the third argument.

Examples

Basic Examples (2) 

A simple locator in 3D:

In[1]:=
Graphics3D[ResourceFunction["Locator3D"][], PlotRange -> 1]
Out[1]=

Use several locators to specify a line:

In[2]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/f09c8288-5493-4795-9146-0382f41ed28b"]
Out[2]=

To use Locator3D inside a Manipulate expression, add the locator manually to the graphic, and specify None as control type:

In[3]:=
Manipulate[
 Graphics3D[
  ResourceFunction["Locator3D"][Dynamic@pt],
  PlotRange -> 1
  ],
 {{pt, {0, 0, 0}}, None}
 ]
Out[3]=

Scope (4) 

Create a movable cube:

In[4]:=
Graphics3D[
 ResourceFunction["Locator3D"][{0, 0, 0}, Cube[], ImageSize -> 0.7],
 PlotRange -> 2
 ]
Out[4]=

Constrain movement to the diagonals instead:

In[5]:=
Graphics3D[
 ResourceFunction["Locator3D"][{0, 0, 0}, Cube[],
  ImageSize -> 1,
  "GuideDirections" -> {{1, 1, 1}, {1, 1, -1}, {1, -1, 1}, {1, -1, -1}}],
 PlotRange -> 2
 ]
Out[5]=

Move the locator in a plane by holding down the -key:

In[6]:=
Graphics3D[
 ResourceFunction["Locator3D"][],
 PlotRange -> 1
 ]
Out[6]=

Allow both rotation and translation, rotate by holding down the -key (Windows/Linux) or -key (macOS):

In[7]:=
Graphics3D[
 ResourceFunction["Locator3D"]["AllowedActions" -> All],
 PlotRange -> 1
 ]
Out[7]=

Options (10) 

ImageSize (1) 

Specify the size of the locator in graphics coordinates:

In[8]:=
Graphics3D[
 {
  Cube[],
  ResourceFunction["Locator3D"][{1, 1, 1}, ImageSize -> 0.3]
  },
 PlotRange -> 1.5
 ]
Out[8]=

GuideDirections (2) 

With the default setting "GuideDirections"Automatic, the locator is movable along the 3 cardinal directions:

In[9]:=
Graphics3D[ResourceFunction["Locator3D"][], PlotRange -> 1]
Out[9]=

Constrain the locator to the xy-plane:

In[10]:=
Graphics3D[
 ResourceFunction["Locator3D"][
  "GuideDirections" -> {{1, 0, 0}, {0, 1, 0}}], PlotRange -> 1]
Out[10]=

ShowGuides (2) 

With the default setting "ShowGuides"True, guide lines and planes are shown when manipulating the locator:

In[11]:=
Graphics3D[ResourceFunction["Locator3D"][], PlotRange -> 1]
Out[11]=

Hide the guides instead:

In[12]:=
Graphics3D[ResourceFunction["Locator3D"]["ShowGuides" -> False], PlotRange -> 1]
Out[12]=

AllowedActions (2) 

With the default setting "AllowedActions"Automatic, the set of allowed actions depends on the other settings of the locator. With nothing else specified, "MoveAlong" and "MovePerpendicular" are allowed:

In[13]:=
Graphics3D[{ResourceFunction["Locator3D"][]}, PlotRange -> 1.5]
Out[13]=

With explicit guide directions specified, "MovePerpendicular" is no longer enabled to force the movement along the specified directions:

In[14]:=
Graphics3D[{ResourceFunction["Locator3D"][
   "GuideDirections" -> {{1, 1, 0}, {1, -1, 0}}]}, PlotRange -> 1.5]
Out[14]=

Specifying a rotation matrix enables "Rotate" as well (and changes the default appearance to a cube):

In[15]:=
Graphics3D[{ResourceFunction[
   "Locator3D"][{{0, 0, 0}, IdentityMatrix[3]}]}, PlotRange -> 1.5]
Out[15]=

Allow only rotation:

In[16]:=
Graphics3D[{ResourceFunction["Locator3D"][
   "AllowedActions" -> "Rotate"]}, PlotRange -> 1.5]
Out[16]=

ModifierKeys (1) 

With the default setting "ModifierKeys"{None,"ShiftKey","OptionKey"}, the first allowed action requires no modifier key, the second one the -key, and the third one the -key (Windows/Linux)/the -key (macOS):

In[17]:=
Graphics3D[ResourceFunction["Locator3D"][], PlotRange -> 1]
Out[17]=

RotateGuides (2) 

With the default setting "RotateGuides"False, the guide directions are kept axis-aligned, even when the locator is rotated:

In[18]:=
Graphics3D[ResourceFunction["Locator3D"]["AllowedActions" -> All], PlotRange -> 1]
Out[18]=

Rotate the guides, keeping them fixed to the coordinate system of the locator:

In[19]:=
Graphics3D[
 ResourceFunction["Locator3D"]["AllowedActions" -> All, "RotateGuides" -> True], PlotRange -> 1]
Out[19]=

Possible Issues (2) 

When using scaled sizes, selecting the arrows is sometimes tricky due to an issue in the front-end (only affects versions 12.3 and lower):

In[20]:=
Graphics3D[{Sphere[], ResourceFunction["Locator3D"][{1, 0, 0}]}, PlotRange -> 1.5]
Out[20]=

Knowing the plot range, you can use absolute sizes instead:

In[21]:=
Graphics3D[{Sphere[], ResourceFunction["Locator3D"][{1, 0, 0}, ImageSize -> 0.25]}, PlotRange -> 1.5]
In[22]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/b3e0851f-f4a8-4da0-9ae4-59a5047cc713"]

Neat examples (6) 

Create a separate rotation control to adjust the orientation of a graphic:

In[23]:=
DynamicModule[
 {rot = IdentityMatrix[3]},
 Row@{
   Graphics3D[
    ResourceFunction["Locator3D"][{{0, 0, 0}, Dynamic[rot]}, "AllowedActions" -> "Rotate", ImageSize -> Scaled[0.25]],
    Boxed -> False, PlotRange -> 1
    ],
   Graphics3D[
    {
     EdgeForm@None,
     GeometricTransformation[
      ExampleData[{"Geometry3D", "StanfordBunny"}, "MeshRegion"],
      Dynamic[rot]
      ]
     }, ImageSize -> 300
    ]
   }
 ]
Out[23]=

Make a simple block building game:

In[24]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/f955c257-77bb-444e-8fdd-ea90b44b07c7"]
Out[24]=

Constrain the locator to the surface of a sphere:

In[25]:=
DynamicModule[{p = {1, 0, 0}}, Graphics3D[{
   {Opacity@0.3, Sphere[{0, 0, 0}, 0.9]},
   ResourceFunction["Locator3D"][Dynamic[p, (p = Normalize@#) &], ImageSize -> 0.3],
   Red,
   Dynamic@Tube@{{0, 0, 0}, p}
   },
  PlotRange -> 1.2
  ]
 ]
Out[25]=

Dynamically update the allowed directions to indicate that the movement is restricted to the sphere:

In[26]:=
DynamicModule[{p = {1, 0, 0}}, Graphics3D[{
   {Opacity@0.3, Sphere[{0, 0, 0}, 0.9]},
   ResourceFunction["Locator3D"][
    Dynamic[p, (p = Normalize@#) &],
    "GuideDirections" :> {Normalize[p\[Cross](p\[Cross]{0, 0, 1})], Normalize[p\[Cross]{0, 0, 1}]},
    ImageSize -> 0.3
    ],
   Red,
   Dynamic@Tube@{{0, 0, 0}, p}
   },
  PlotRange -> 1.2
  ]
 ]
Out[26]=

Tweak the normalization to prevent drifts of the point when moving too quickly around the z-axis:

In[27]:=
DynamicModule[{p = {1, 0, 0}, z0},
 Graphics3D[{
   {Opacity@0.3, Sphere[{0, 0, 0}, 0.9]},
   ResourceFunction["Locator3D"][Dynamic[
     p, {
      (z0 = #[[3]]) &,
      (If[#3 == 2,
         p[[;; 2]] = Normalize@#[[;; 2]] Sqrt[1 - z0^2],
         p = Normalize@#
         ]) &,
      Automatic
      }
     ], "GuideDirections" :> {p\[Cross](p\[Cross]{0, 0, 1}), p\[Cross]{0, 0, 1}}, ImageSize -> 0.3
    ],
   Red, Dynamic@Tube@{{0, 0, 0}, p}
   },
  PlotRange -> 1.5
  ]
 ]
Out[27]=

Create a version based on the "MovePerpendicular" action, where the guide plane is hidden in favor of the sphere:

In[28]:=
DynamicModule[{p = {1, 0, 0}}, Graphics3D[{
   {Opacity@0.3, Sphere[{0, 0, 0}, 0.9]},
   ResourceFunction["Locator3D"][
    Dynamic[p, (p = Normalize@#) &],
    "GuideDirections" :> {p},
    "AllowedActions" -> "MovePerpendicular",
    "ShowGuides" -> False,
    ImageSize -> 0.3
    ],
   Red,
   Dynamic@Tube@{{0, 0, 0}, p}
   },
  PlotRange -> 1.3
  ]
 ]
Out[28]=

Publisher

Lukas Lang

Version History

  • 1.0.1 – 19 September 2022
  • 1.0.0 – 28 June 2022

Related Resources

Author Notes

Changes from version 1.0.0 to 1.0.1:

Fixed an issue where Locator3D inside Manipulate caused unexpected reevaluations when holding down modifier keys.

License Information