3
$\begingroup$

This makes a slider to control the number of points. Click in the Graphics and the points slide over to where you click.

Manipulate[
DynamicModule[{points,oldPoints,centerG,oldCenterG,finalPnts,mousePosn},
points=Map[{10,12}+#&,Table[{Cos[2.0 Pi k/n],Sin[2.0 Pi k/n]},{k,1,n}]];
oldPoints=finalPnts=points;
oldCenterG=centerG=Mean/@Transpose[points];

Dynamic[EventHandler[Framed[Graphics[{PointSize[0.02],Point[
If[TrueQ[points==finalPnts],
oldCenterG=centerG;
oldPoints=points,
(* else *)
points=MapThread[
With[{mag=Norm[#2-#1]},If[TrueQ[mag<=0.02],#2,#1+0.04(#2-#1)/mag]]&,
{points,finalPnts}]
]
]},PlotRange->{{-15,15},{-15,15}},ImageSize->{600,600}]],
{"MouseDown":>(
mousePosn=MousePosition["Graphics"];
centerG=Mean/@Transpose[points];
finalPnts=Map[(#+mousePosn-oldCenterG)&,oldPoints]) ,
"MouseUp":>(centerG=mousePosn)
}]] 
],{{n,3},3,8,1}]

The problem is that my real application doesn't allow use of Manipulate. I thought the code below would work, but it breaks when you click in the Graphics. How to get the second version working?

DynamicModule[{points, oldPoints, centerG, oldCenterG, finalPnts, 
  mousePosn, n},

 points = 
  Dynamic[Map[{10, 12} + # &, 
    Table[{Cos[2.0 Pi k/n], Sin[2.0 Pi k/n]}, {k, 1, n}]]];
 oldPoints = finalPnts = points;
 oldCenterG = centerG = Mean /@ Transpose[points];

 Column[{
   Slider[Dynamic[n], {3, 8, 1}],
   Dynamic[EventHandler[Framed[Graphics[{PointSize[0.02], Point[
         If[TrueQ[points == finalPnts],
          oldCenterG = centerG;
          oldPoints = points,
          (* else *)
          points = MapThread[

            With[{mag = Norm[#2 - #1]}, 
              If[TrueQ[mag <= 0.02], #2, #1 + 0.04 (#2 - #1)/mag]] &,
            {points, finalPnts}]
          ]
         ]}, PlotRange -> {{-15, 15}, {-15, 15}}, 
       ImageSize -> {400, 400}]],
     {"MouseDown" :> (
        mousePosn = MousePosition["Graphics"];
        centerG = Mean /@ Transpose[points];
        finalPnts = Map[(# + mousePosn - oldCenterG) &, oldPoints]) ,
      "MouseUp" :> (centerG = mousePosn)
      }]]}]]
$\endgroup$
3
  • $\begingroup$ Ted can you explain why you can't use Manipulate? This can obviously be re-written as a DynamicModule but are you able to use that? What is causing your restrictions? $\endgroup$ Jun 12, 2012 at 23:08
  • $\begingroup$ Sorry for being a pain, but I still haven't learned how to format the code. Much of the time I come here using my iPhone which has many features in stack exchange missing. Sometime when I am at home, I will try to contact one of you on chat and learn some stuff. Want my email address? $\endgroup$
    – Ted Ersek
    Jun 12, 2012 at 23:42
  • $\begingroup$ No worries, using SE from an iPhone can be a pain. One solution might be to not post long questions from an iPhone. In any case, you're always welcome to drop by our chatroom if you have any questions on the site/formatting/etc... it's usually active with some casual chatter going on. $\endgroup$
    – rm -rf
    Jun 13, 2012 at 0:18

2 Answers 2

4
$\begingroup$

This is a DynamicModule version of your code. I haven't sought to modify it in any way other than to convert from Manipulate to DynamicModule:

DynamicModule[{points, oldPoints, centerG, oldCenterG, finalPnts, 
  mousePosn, n = 3},

 Column[{
   Manipulator[Dynamic[n], {3, 8, 1}],
   Dynamic[
   points = Map[{10, 12} + # &,Table[{Cos[2.0 Pi k/n], Sin[2.0 Pi k/n]}, {k, 1, n}]]; 
    oldPoints = finalPnts = points; 
    oldCenterG = centerG = Mean /@ Transpose[points]; 
    EventHandler[
     Framed[Graphics[{PointSize[0.02], 
        Point[If[TrueQ[points == finalPnts], oldCenterG = centerG; 
          oldPoints = points,(*else*)
          points = MapThread[With[{mag = Norm[#2 - #1]}, 
              If[TrueQ[mag <= 0.02], #2, #1 + 0.04 (#2 - #1)/mag]] &, {points, finalPnts}]]]}, 
       PlotRange -> {{-15, 15}, {-15, 15}}, 
       ImageSize -> {600, 600}]], 
      {"MouseDown" :> (mousePosn = MousePosition["Graphics"]; 
        centerG = Mean /@ Transpose[points]; 
        finalPnts = Map[(# + mousePosn - oldCenterG) &, oldPoints]), 
      "MouseUp" :> (centerG = mousePosn)}]
    ]

   }]
 ]

Edit

When I posted this answer you hadn't posted your attempt. The problem with the code was that point, oldpoints and oldCenterG were not configured to dynamically update. Bringing them into the Dynamic now makes them update when n changes. Also you haven't given n a starting value whereas with your Manipulate you had.

$\endgroup$
2
$\begingroup$

I "needed to" avoid using Manipulate because, in my real application, the number of points in the graphic isn't controlled with a slider. The number and placement of the points is cotrolled with

LocatorPane[Dynamic[pts],Framed@Graphics[{}],LocatorAutoCreate->True]]  

Well it might have been possible to get it working with Manipulate, but I couldn't figure it out. Anyway I figured out a way to solve the problem. I think my earlier attempt didn't work because Head[points] was Dynamic. The code below works great. Actually, in my solution below I deleted stuff that was irrelevant to the problem I was having.

DynamicModule[{points,points0,oldPoints,centerG,centerG0,oldCenterG,
  finalPnts,mousePosn,n},
  Column@{Slider[Dynamic[n,(
    finalPnts=points=Table[{Cos[2.0 Pi k/#],Sin[2.0 Pi k/#]},{k,1,#}];
    centerG=oldCenterG={0,0};
    n=#)&],{3,8,1}],
  Dynamic@EventHandler[Framed@Graphics[{
    Point@If[points==finalPnts,
      oldCenterG=centerG;oldPoints=points,
      (* else *)
      points=MapThread[With[{mag=Norm[#2-#1]},
         If[mag<=0.02,#2,#1+0.04(#2-#1)/mag]]&,{points,finalPnts}]
      ]},PlotRange->{{-9,9},{-9,9}}
  ],
  {"MouseDown":>(
    mousePosn=MousePosition@"Graphics";
    centerG=Mean/@Transpose@points;
    finalPnts=(#+mousePosn-oldCenterG)&/@oldPoints),
  "MouseUp":>(centerG=mousePosn)
}
]}]

I think it's a good illustation of programming with Dynamic and EventHandler.

$\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.