4

I am attempting to set an EventHandler to change the radius of a circle by dragging on its circumference. But the response to the dragging is terribly slow. What is wrong with the code?

cnt[p_] := Return[Round /@ p];
grids[min_, max_] := 
  Join[Range[Ceiling[min], Floor[max]], 
   Table[{j + 1, Lighter@Lighter@Lighter@Lighter@Blue}, {j, 
     Round[min], Round[max - 1], 1}]];

DynamicModule[{pnt = {1, 1}, VPOS = {1, 1}, rad = 1},
  Dynamic@Graphics[
   {Thick,
    EventHandler[
     Circle[ cnt[pnt] , rad],
     {
      "MouseDragged" :> (
        VPOS = MousePosition["Graphics"];
          rad = EuclideanDistance[pnt, VPOS];
        )
      },
     PassEventsDown -> True
     ],
    Locator[Dynamic[pnt], None] 
    },
   Axes -> True,
   GridLines -> grids,
   PlotRange -> {{-10, 10}, {-10, 10}}] 
 ]

enter image description here

Putterboy
  • 4,661
  • 1
  • 19
  • 30
  • Is EventHandler a need? Using Locator might be easier. – Öskå Aug 01 '14 at 10:42
  • Yes, I am trying to test how to correctly set an EventHandler. – Putterboy Aug 01 '14 at 10:50
  • It's probably slow because of the EuclideanDistance. – Öskå Aug 01 '14 at 10:56
  • 1
    Is it again the problem of out of focus? Seems it only response when the mouse is right on the top of the circumference. Is there a way of work-around? – Putterboy Aug 01 '14 at 11:06
  • Can you clarify what you are trying to do? I can move the circle when I click the mouse on its center, and when I mouseclick on the circumference, the size changes. Are you interested in being able to both move the circle and change its size with the mouse? – bobthechemist Aug 01 '14 at 11:38
  • @bobthechemist I think the problem is that the circle doesn't move when you move your mouth, it just moves a few milliseconds after. – Öskå Aug 01 '14 at 11:47
  • @bobthechemist Yes, exactly. It is no problem to move the circle, but it is hardly to change its size. – Putterboy Aug 01 '14 at 12:10

1 Answers1

3

The front end's event handling mechanism seems to have a hard time deciding which event should be passed to the locator. Therefore, I think it's best to dispense with the locator. This seems to work fairly well:

cnt[p_] := Return[Round /@ p];

grids[min_, max_] :=
  Join[
    Range[Ceiling[min], Floor[max]], 
    Table[{j + 1, Lighter @ Lighter @ Lighter @ Lighter @ Blue}, 
      {j, Round[min], Round[max - 1], 1}]];

DynamicModule[{pnt = {1, 1}, VPOS = {1, 1}, rad = 1, d},
 EventHandler[
   Dynamic @ 
     Graphics[{{PointSize[Medium], Point[cnt[pnt]]}, {Thick, Circle[cnt[pnt], rad]}},
       Axes -> True,
       GridLines -> grids,
      PlotRange -> {{-10, 10}, {-10, 10}}],
  {"MouseDragged" :> (
     VPOS = MousePosition["Graphics"];
     d = EuclideanDistance[pnt, VPOS]; 
     If[d < 1, pnt = VPOS, rad = d])}]]

graphics

I made the center point visible as an aid to dragging the circle from grid point to grid point. I also need to point out that, when adjusting the radius, it is best to drag from just outside the circle.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
  • It's much better than the OP's answer indeed, but moving the centre too fast catches the circle sometimes.. – Öskå Aug 01 '14 at 14:22
  • @Öskå. Yeah, that's why I wrote "This seems to work fairly well" rather than "This seems to work well". It does meet the requirement of moving the circumference smoothly. – m_goldberg Aug 01 '14 at 14:26