5
$\begingroup$

Based on the example of the Documentation of MousePosition, Properties and Relations, here is my test code using "MouseDragged" instead of "MouseClicked":

DynamicModule[{list = {}},
 EventHandler[
  Dynamic[
   Framed@Graphics[{Red, Point[list]}, PlotRange -> 2]
   ]
  , {"MouseDragged" :> AppendTo[list, MousePosition["Graphics"]]}
  ]
 ]

Using this, one can drag lines of dots as follows:

enter image description here

The top line was drawn while moving the mouse very slowly, the bottom line was drawn with a faster mouse movement.

I would now like to add even more points in the bottom line, to be able to have an almost full line, even with fast mouse movements. I have checked out Refresh, and UpdateInterval, but that didn't change everything.

So: is it possible to track all pixel movements of the mouse inside a certain region, to be able to plot all points?

As always, thanks for all help!

$\endgroup$
5
  • $\begingroup$ What OS do you use? Is your mouse a USB one? The bottleneck COULD be the OS level, as it is said "by default, the USB polling rate is set at 125hz.". $\endgroup$
    – Silvia
    Commented Dec 22, 2013 at 18:27
  • $\begingroup$ I use Mac OS 10.9 and I use the mouse on the trackpad of the laptop. Do you have different results? $\endgroup$
    – Gabriel
    Commented Dec 22, 2013 at 18:28
  • $\begingroup$ I'm under win8 and I think I have approached the OS limit in Dynamic. But I need more evidence.. $\endgroup$
    – Silvia
    Commented Dec 22, 2013 at 18:33
  • $\begingroup$ What do you mean with OS limit? I don't follow... $\endgroup$
    – Gabriel
    Commented Dec 22, 2013 at 18:35
  • 1
    $\begingroup$ One OS limit is that the mouse actually jumps from position to position. You may be capturing all of the positions with your code. $\endgroup$
    – Michael E2
    Commented Dec 22, 2013 at 18:42

2 Answers 2

6
$\begingroup$

The following seems to be a little faster, most likely because it avoids AppendTo.

DynamicModule[{list = {}},
  EventHandler[
   Dynamic @ Framed @ Graphics[{Red, list}, PlotRange -> 2], 
   {"MouseDragged" :> 
     (list = Flatten @ {list, Point @ MousePosition["Graphics"]})}]]

However, you might find it more to your liking to use lines rather than points. Doing so will allow for nice, smooth lines to be drawn. Here is one way to modify your code to use lines.

DynamicModule[{new, old, current = {}, previous = {}},
  EventHandler[
    Dynamic @ Framed @ Graphics[{{Red, previous}, {Black, current}}, PlotRange -> 2], 
    {"MouseDragged" :> 
      (current = 
         Flatten @ {current, Line @ {old, new = MousePosition["Graphics"]}}; 
       old = new),
     "MouseDown" :> (old = MousePosition["Graphics"]; current = {}),
     "MouseUp" :> (previous = Flatten@{previous, current})}]]

drawing.png

$\endgroup$
6
$\begingroup$

I'm not sure how to increase the mouse polling rate in Dynamic-things, but I think it has been doing really well on my computer, which is Windows 8.1 with a regular USB mouse.

Here is a simple code to measure the average polling rate of Dynamic:

Module[{mplst = {}, time = 10},
       PrintTemporary[DynamicWrapper["Measuring...",
                     mplst = Join[mplst, {MousePosition[]}]
                     ]];
       Pause[time];
       Length[mplst]/time // N
      ]

which gives near $100\, \mathrm{Hz}$ result.

This is the result mesured by tool based on DirectX:

true mouse polling rate

I think it's fair to say Dynamic does his job pretty well.

I noticed there is saying that "USB polling rate is set at 125hz" by default. So I will not be surprised if using a high-rate mouse get a better result.

Also, you should be aware that the AppendTo might slow down your code when list gets big. Please see section 3 in this post for detail.

Update:

Here is a preciser measurement of, I think, the polling rate of MousePosition itself without the affection of Dynamic.

Put the cursor in the code, keep moving your mouse (but not too fast), meanwhile press Shift + Enter:

mplst = {};
time = AbsoluteTiming[Do[
                         mplst = {mplst, MousePosition[]},
                         {10^4}]][[1]];
mplst = mplst // Flatten // Partition[#, 2] &;
freshrate = 10^4/time

3645.44

It's a HELL of high rate!

But wait... If we take a look into mplst, we'll see many of them are duplicates:

trueTrackPt = mplst // Split // #[[All, 1]] &;
mouseFreshrate = Length[trueTrackPt]/time

124.3093

This is really close to the result from the DirextX tool, which could be considered as the true rate.

For a much faster mouse movement, the freshrate will be greater, but the mouseFreshrate will be less.

So I think the mouse polling rate in Dynamic might be able to be increased within Mathematica (with methods which I haven't found yet), but only with a limited amount. The true bottleneck is still the OS and hardware, to overcome which you'll have to have special drivers and/or a high-rate mouse.

On the other hand, if all you need is smoother trajectory, you can try draw it more slowly, link the sample points with Line or BSplineCurve, even Interpolation them:

Graphics[{Lighter[Blue, .4], Thick, Line[trueTrackPt],
          White, Thin, BSplineCurve[trueTrackPt],
          Red, Point[trueTrackPt]},
         Background -> Black]
$\endgroup$
9
  • $\begingroup$ Thanks, Silvia, for your answer. I get 57. as result with your code, using the trackpad mouse on the Mac machine. Has someone a Mac and could test this too? Thanks! $\endgroup$
    – Gabriel
    Commented Dec 22, 2013 at 19:45
  • $\begingroup$ In my machine the result depends on whether or not you actually move the mouse. It seems that moving the mouse pointer eats up some cycles ... $\endgroup$ Commented Dec 22, 2013 at 20:15
  • $\begingroup$ @Gabriel I obtain a similar number on my Mac OS X 10.9 machine with a Bluetooth Magic Mouse but by removing the Join from Silvia's code, e.g. using mplst={mplst,MousePosition[]} and Length[Flatten[mplst]]/time I can increase that to "near 100 Hz". $\endgroup$ Commented Dec 23, 2013 at 11:47
  • $\begingroup$ @belisarius Here in fact if I put mouse focus out side MMA, the result will be max. And I do think Dynamic has not achieved the best performance that MousePosition can do.. I'll update some code later. $\endgroup$
    – Silvia
    Commented Dec 23, 2013 at 12:05
  • $\begingroup$ @MikeLimaOscar I tried your way at first, but it kept crashing my Mathematica, so I have to go the slow way... :( But it's good to know that it's my code rather than Dynamic which limits the performance. $\endgroup$
    – Silvia
    Commented Dec 23, 2013 at 12:07

Your Answer

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

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