# Controlling point in graphics 3D with locator

I want to control a point in 3D graph by dragging it with the mouse lets say this is my code and I want to add some functionality like the way locator works in 2d graphics

  Manipulate[
Graphics3D[{Black, PointSize[0.02], Point[pt]}, ImageSize -> Large,
PlotRange -> {{-10, 10}, {-10, 10}, {-10, 10}
}, Axes -> True], {{pt, {1, 1, 1}}, {-5, -5, -5}, {5, 5, 5},**Locator**}]

• Does this answer your question? How can locators be added to the points on a 3D grid? Commented Sep 13, 2022 at 12:48
• You might be interested in ResourceFunction["Locator3D"] - it is intended to be a drop-in replacement for Locator in 3D. (Apart from the fact that you can't use it as control type for Manipilate) - I'll add a more concrete answer once I'm back at my PC Commented Sep 13, 2022 at 13:08

Well, I wrote an interactive Variable Calculus book and, as I don't know a "3D locator", I used mouse events to select and drag points. I learned the code from several posts. Here I share tow basic examples

First one you can see in here. Second one follow

The code is

Manipulate[Grid[{
(*Titulos*)
{Style["Puntos en 3D", Bold, 10,RGBColor[0.12, 0, 0.5]]},
{
(*------------------------------------------    3D      --------------------*)
DynamicModule[{pts={{2,0,2},{0,2,1}},index=0,pos0,pos1,mypr={{-2,4},{-2,4},{-2,4}},AV1Cap1Obj},
(*Objetos*)
If[var==2,{PointSize[0.03], Point[Dynamic@pts[[2]]],FaceForm[],EdgeForm[], Cuboid[Dynamic[pts[[2]]-{0.5,0.5,0.5}]]   } ]   ];
(*       *)
EventHandler[
Graphics3D[{
AV0Cap1ejes,
(*----------   Parte dinámica --------------*)
Dynamic[{Text[,1.1pts[[2]],{0,-1}],
Dashed, Thick, RGBColor[0, 0.3, 0], Gray,
Line[{{pts[[2,1]],0,0},{pts[[2,1]],pts[[2,2]],0},{0,pts[[2,2]],0}}],Line[{{pts[[2,1]],pts[[2,2]],0},pts[[2]],{0,0,pts[[2,3]]}}],
Text[Style[NumberForm[Round[pts[[2,1]],0.1],2],Bold,10],{pts[[2,1]],-0.4,0}],
Text[Style[NumberForm[Round[pts[[2,2]],0.1],2],Bold,10],{-0.4,pts[[2,2]],0}],Text[Style[NumberForm[Round[pts[[2,3]],0.1],2],Bold,10],{0,-0.4,pts[[2,3]]}]
}],
MouseAppearance[EventHandler[ (*Función: Aplica # a {1,2,...}*)
Mouseover[
{ (*expr base, mouse fuera*)
Dynamic[If[index===#,Red,RGBColor[0, 0.34, 0]]],AV1Cap1Obj[#]
},
{(* mouse over*)
Dynamic[If[index===0||index===#,Red,RGBColor[0, 0.34, 0]]],AV1Cap1Obj[#]
}
](*MouseOver*),
{"MouseDown":>(index=#;pos0=pts[[index]]) (*Selecciona: pos0 = posición actual*)
},
PassEventsUp->True]&/@Range[Length[pts]](*EventHandler local, #=1,2,....*),"Arrow"]
} (*Opciones Graphics3D*)

,{ (*Si arrastra...*)
"MouseDragged":>If[index>0,((pos1=#[[2]]+Projection[pos0-#[[2]],#[[1]]-#[[2]]])&@MousePosition["Graphics3DBoxIntercepts"]);
pts[[index]]=pos1
], (*Clip puntos*)
"MouseUp":>(pts[[All,3]]=Clip[pts[[All,3]],{-1.8,2.8}];pts[[All,2]]=Clip[pts[[All,2]],{-1.8,2.8}];pts[[All,1]]=Clip[pts[[All,1]],{-1.8,2.8}];
index=0)
},
(*Pass the events to LocatorPane by setting PassEventsDown\[Rule]True in the deepest event handlers*)
PassEventsDown->True](*EventHandler Global*)
](*DynamicModule*)
}}, Alignment->Top], (*Grid*)
(*-------Manipulate------*)
ContentSize ->Automatic,
ControlPlacement->Top,
AppearanceElements->None,
Alignment->{Top},
SaveDefinitions->True,
SynchronousInitialization->False,
Initialization:>{ violeta=RGBColor[0.12, 0, 0.5];
Ejes3DTxy[xmin_,xmax_,ymin_,ymax_,zmin_,zmax_]:={
Arrow[Tube[{{xmin,0,0.01},{0,0,0.01},{xmax,0,0.01}},0.007]],
Arrow[Tube[{{0,ymin+0.01,0.01},{0,0,0.01},{0,ymax+0.01,0.01}},0.007]],
Arrow[Tube[{{0.01,0.01,zmin+0.01},{0.01,0.01,0.01},{0,0,zmax+0.01}},0.007]],
Gray,
Table[Line[{{IntegerPart[xmin],i,0},{IntegerPart[xmax],i,0}}],{i,IntegerPart[ymin],IntegerPart[ymax],1}],Table[Line[{{i,IntegerPart[ymin],0},{i,IntegerPart[ymax],0}}],{i,IntegerPart[xmin],IntegerPart[xmax],1}],
};
AV0Cap1ejes=Ejes3DTxy[-1,3,-1,3,0,3];
wNformat[var_]:=Style[NumberForm[Round[ var ,0.1],3],Bold,12,RGBColor[0.23, 0, 0.70]]}]


You can use ResourceFunction["Locator3D"] as follows:

Manipulate[
Graphics3D[
{Black, PointSize[0.02], ResourceFunction["Locator3D"][Dynamic@pt]},
ImageSize -> Medium,
PlotRange -> {{-10, 10}, {-10, 10}, {-10, 10}},
Axes -> True
],
{{pt, {1, 1, 1}}, None}
]


Note how I set the control type of pt to None, and added the locator to the graphics myself. This is currently necessary, as Manipulate doesn't support custom "fancy" controls that merge with the content (effectively what is done for Locator). If you want to impose limits on the location of the locator, use the two-argument form of Dynamic (examples for how this works can also be seen in the documentation for Locator):

Manipulate[
Graphics3D[
{Black, PointSize[0.02],
ResourceFunction["Locator3D"][
Dynamic[pt, (pt = Clip[#, {-5, 5}]& /@ #)&]]
},
ImageSize -> Medium,
PlotRange -> {{-10, 10}, {-10, 10}, {-10, 10}},
Axes -> True
],
{{pt, {1, 1, 1}}, None}
]


This resets the position to the allowed region before actually assigning it to pt.

• Thanks for the answer it's helpful, but the function PointSize[#] is not effective either the color can not be changed in this form, do you know how to change the point size or the color? because this {Black, Point Size[0.02] ...} is not effective Commented Sep 18, 2022 at 14:59
• @TtTt If you are talking about changing the appearance of the sphere: similarly to the 2D locator, the appearance can be controlled using the second argument of Locator3D (see also the examples in the "Scope" section of the documentation). For reference, the default is something like {Black, Sphere[{0,0,0}, Scaled[0.05]]}. Note that you might also need to change the size of the handles (the colored arrows), this can be done using the ImageSize option (agian, see the examples in the documentation) Commented Sep 18, 2022 at 16:19
• @TtTt FYI, the fixed version of the function is now available from the repository, so ResourceFunction["Locator3D"] is all you need (you might need to update your local version using ResourceUpdate@ResourceFunction["Locator3D"]) Commented Sep 19, 2022 at 20:39