9
$\begingroup$

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**}]
$\endgroup$
2

2 Answers 2

13
$\begingroup$

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}
 ]

enter image description here

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.

$\endgroup$
3
  • $\begingroup$ 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 $\endgroup$
    – Tt Tt
    Sep 18, 2022 at 14:59
  • $\begingroup$ @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) $\endgroup$
    – Lukas Lang
    Sep 18, 2022 at 16:19
  • $\begingroup$ @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"]) $\endgroup$
    – Lukas Lang
    Sep 19, 2022 at 20:39
12
$\begingroup$

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

enter image description here

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*)
AV1Cap1Obj[var_]:=If[var==1,{Thickness[0.0001],Arrowheads[0.00], Arrow[ {{0,0,0},{0,0,0}} ]  },
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*)
,PlotRange->mypr,ImageSize->350, ViewPoint->{1,1, 0.6}, Boxed->False,ImagePadding->None,SphericalRegion->True](*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_]:={
Black,Arrowheads[Medium],
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]]}]
$\endgroup$

Your Answer

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

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