0
$\begingroup$

I would like to write a simple code that samples mouse position as frequently as the system can handle (with minimum dt) starting when the mouse position leaves a region and ending when the mouse position enters a different region. Without the regions, this is done simply by

pointlist = {};
dt = 1/100; (*max 1/dt samples per second *)
total = 4; (*total time in seconds *)
starttime = AbsoluteTime[];
Do[
  AppendTo[pointlist, Flatten@{AbsoluteTime[], MousePosition[]}];
  Pause[dt];
  , {i, total/dt}];

Looking through MousePosition[] and MouseOver[] documentation it seems that there should be a way to use EventHandler[] but the examples and actions seem graphically based. And while statements like

If[CurrentValue["MouseOver"], 0, 1]

seem like they should work, I get nothing when I put it into a While loop:

pointlist = {};
dt = 1/100; (* 1/dt samples per second *)
starttime = AbsoluteTime[];
While[
 Dynamic[If[CurrentValue["MouseOver"], "A", "B"] == "B"], 
 AppendTo[pointlist, Flatten@{AbsoluteTime[], MousePosition[]}];
 Pause[dt];]

Essentially, I want for regions A and B

While[MousePosition[] \nin A \cup B, AppendTo[pointlist, Flatten@{AbsoluteTime[], MousePosition[]}];
      Pause[dt]; ]

where \nin is the usual "not in" and "cup" is the usual union. Once this mechanism is worked out, I can add my own bells and whistles.

$\endgroup$
  • 1
    $\begingroup$ Using a While command with a Dynamic expression in the first argument will not do anything, because of a Dynamic expression always evaluates to a Dynamic expression and never to True. A displayed DynamicExpression may show True, but nevertheless the expression still has head Dynamic. If you can post an example of a region, I will see if I can construct your pointlist when the mouse moves over the region. $\endgroup$ – Fred Simons Apr 20 '15 at 6:27
1
$\begingroup$

The following might give you some idea how it could be done. I assume that your regions are given by a Boolean function of two arguments, and therefore can be displayed with RegionPlot. For example, when your region is a circle, the region function is

region=#1^2+#2^2<=1&

and the region can be displayed as follows:

RegionPlot[region[x,y], {x,-1,1},{y,-1,1}, ImageSize->200]

Now let us try to catch the position of the mouse when it is over the region. That can be done by placing the region plot in an event handler. There is not something like an event Mouseover, but we can use the event MouseMoved. Only when the moved mouse is over the region, we want to append the position to pointlist. Obviously, for testing if the mouse is over the region, we can use the region function by which we constructed the region. Here is an example, where the region is the circle. The first graphics is the event handler, the second graphics shows the result.

pointlist={}; 
Column[{ 
  EventHandler[RegionPlot[region[x,y], {x,-1,1},{y,-1,1}, ImageSize->200]//Deploy,
    {"MouseMoved":>With[{z=MousePosition["Graphics"]}, 
       If[region@@z,AppendTo[pointlist,z]]]}], 
  Graphics[{Circle[],Dynamic[Line[pointlist]]}, PlotRange->1, ImageSize->200] 
}]

When you move the mouse over the first graphics, in the second graphics you see that the orbit is only caught when the mouse is over the region.

I think this example can easily be modified to what you want to do. In the event handler, you can not only add to pointlist the position of the mouse, but also the time when this happens, as you have shown already. When you want to consider more regions simultaneously, you can logically combine the corresponding region functions.

$\endgroup$
  • $\begingroup$ Thanks! That worked perfectly. I've added my own answer which took care of the original problem, but did not let me track "MouseDown" events and things of this nature. $\endgroup$ – cryomath Apr 20 '15 at 20:23
0
$\begingroup$

While Fred Simons's answer is more flexible, I thought I'd add my own for the record because it doesn't depend on the EventHandler structure, nor any specific graphics drawn on the notebook. It seems that one can get access to MousePosition[] through CurrentValue[] which allows something like:

dt = 1/100; (* 1/dt samples per second *)
While[
 Norm[CurrentValue["MousePosition"] - endlocation] > radius,
 AppendTo[pointlist, 
  Flatten@{AbsoluteTime[] - starttime, CurrentValue["MousePosition"]}];
 Pause[dt];]

For the second part of my little program, I wanted the user to move back to the their expected start position and click, but I was not able to make CurrentValue["MouseButtonTest"] work: e.g. this is always False:

Dynamic[CurrentValue["MouseButtonTest"]]

This is fairly easily handled with Fred Simons's answer.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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