0

i am using the following method in python to get the X,Y corordinates at any given this

data = display.Display().screen().root.query_pointer()._data 
x = data["root_x"] 
y = data["root_y"] 
z = time.time()

I want to calculate the mouse speed over a given time, is there any way i can calculate and show mouse speed in miles per hour???

krisdigitx


i now managed to fix the problem and calculated the speed between the last two known x and y positions using this method

        dx = float(x) - float(a1)
        dy = float(y) - float(b1)
        dist = math.sqrt( math.pow(dx,2) + math.pow(dy,2))
        dz = float(z) - float(c1)
        speed = float(dist/dz)

now what rule should i follow to convert the speed to miles per hour?? thanks for all your help, this is the output in realtime..

speed = 1512.53949852 Time = 4:30:690187 CPUTime = 1312531470.7 X = 701 Y = 600 PX = 692 PY = 605 PT = 1312531470.69
speed = 0.0 Time = 4:30:697020 CPUTime = 1312531470.7 X = 701 Y = 600 PX = 701 PY = 600 PT = 1312531470.7
speed = 1563.45505256 Time = 4:30:703667 CPUTime = 1312531470.73 X = 734 Y = 586 PX = 701 PY = 600 PT = 1312531470.7
speed = 0.0 Time = 4:30:726614 CPUTime = 1312531470.73 X = 734 Y = 586 PX = 734 PY = 586 PT = 1312531470.73
speed = 882.257032576 Time = 4:30:735274 CPUTime = 1312531470.76 X = 753 Y = 580 PX = 734 PY = 586 PT = 1312531470.73
speed = 0.0 Time = 4:30:756930 CPUTime = 1312531470.76 X = 753 Y = 580 PX = 753 PY = 580 PT = 1312531470.76
speed = 363.108272412 Time = 4:30:764397 CPUTime = 1312531470.79 X = 762 Y = 580 PX = 753 PY = 580 PT = 1312531470.76
speed = 373.79057125 Time = 4:30:789201 CPUTime = 1312531470.8 X = 765 Y = 580 PX = 762 PY = 580 PT = 1312531470.79
speed = 92.0338354526 Time = 4:30:797211 CPUTime = 1312531470.82 X = 767 Y = 580 PX = 765 PY = 580 PT = 1312531470.8
speed = 0.0 Time = 4:30:818938 CPUTime = 1312531470.83 X = 767 Y = 580 PX = 767 PY = 580 PT = 1312531470.82
speed = 46.9571214259 Time = 4:30:826073 CPUTime = 1312531470.85 X = 767 Y = 579 PX = 767 PY = 580 PT = 1312531470.83
speed = 0.0 Time = 4:30:847362 CPUTime = 1312531470.85 X = 767 Y = 579 PX = 767 PY = 579 PT = 1312531470.85
krisdigitx
  • 7,068
  • 20
  • 61
  • 97
  • 9
    miles per hour? really? – Donald Miner Aug 01 '11 at 17:51
  • yess.. is that possible, basically calucalte the velocity of the cursor over any x and Y corodinates with time and use the formula – krisdigitx Aug 01 '11 at 17:53
  • 1
    You could get the position in pixel coords but I'm not sure there's any way to get the pixel density of the display, which would be required for relating pixels to... miles. – Rob Lourens Aug 01 '11 at 17:56
  • Ok actually, you could hack something together using http://stackoverflow.com/questions/502282/finding-the-workspace-size-screen-size-less-the-taskbar-using-gtk and http://stackoverflow.com/questions/3129322/how-do-i-get-monitor-resolution-in-python but I'm not going to post an answer because I haven't tested it. – Rob Lourens Aug 01 '11 at 17:59

3 Answers3

1

Store the start position and end position, as well as the start time and end time. Get the distance, then divide by the time. That gives you a speed. Presumably that speed is pixels per millisecond, so you just need to convert that to the units you want (miles per hour).

# Start
data = display.Display().screen().root.query_pointer()._data 
x = data["root_x"] 
y = data["root_y"] 
z = time.time()

# Time passes...

# End
data = display.Display().screen().root.query_pointer()._data 
x2 = data["root_x"] 
y2 = data["root_y"] 
z2 = time.time()

# Determine distance traveled
dx = x2 - x1
dy = y2 - y1
dist = math.sqrt( math.pow(dx, 2) + math.pow(dy, 2) ) # Distance between 2 points

# Get the change in time
dz = z2 - z1

# Print out the speed
print "I've traveled {0}".format(dist/dz)
# Convert that to the units you want
thegrinner
  • 11,546
  • 5
  • 41
  • 64
  • i am running this in a while loop so how do i store the first x and y coordinate and then subtract this from the new x,y coordinate when the loop runs.... – krisdigitx Aug 01 '11 at 18:04
  • @krisdigitx Are you wanting to compare all positions to the original, or just the previous? – thegrinner Aug 01 '11 at 18:21
  • @krisdigitx Then you just need to sample inside your `while` loop. The way I did it here stores the first x and y as separate variables from the second x and y with code in between. I assume whatever library you're using refreshes the XY position of the mouse when you call `display.Display().screen().root.query_pointer()._data` so I grab the data twice. If there isn't enough code between to be useful for you, you could treat x and y as lists, using `x.append(data["root_x"])` and comparing the most recent two values. – thegrinner Aug 02 '11 at 13:19
  • cool, i ran this as a loop and calculed the speed of mouse between the last two know positions and it gives a splendid result. How can the speed be converted into miles per hour? – krisdigitx Aug 05 '11 at 07:56
  • If your library has a way to determine the pixel density of a screen, you can get the number of pixels per inch (or a similar unit). Then it's simply a matter of unit conversions: `(miles per hour) = (pixels per second) / (pixels per inch) / (inches per mile) * (seconds per hour)`, so roughly `(speed) / (density) * 3600`. The ugly part of this is that screen density will vary, so if you don't know the density you'll have to fudge that number and by extension the mph. – thegrinner Aug 05 '11 at 13:34
1

If you're running this in a loop, just get an initial sample before entering the loop and then take a position on each iteration, replacing the initial position with the newer one each time.

import math
import collections
import time

PIXEL_MILE_RATIO = 6336000 # assumes 100 pixels/inch
                           # you'll need to come up with a value for this
pixels_to_miles = lambda p: p*PIXEL_MILE_RATIO

Sample = collections.namedtuple('Sample', 'x,y,z')

def calculate_speed(sample1, sample2):
    distance = math.sqrt((sample2.x - sample1.x)**2 + (sample2.y - sample1.y)**2)
    hours = (sample2.z - sample1.z) / 3600.
    return pixels_to_miles(distance)/hours


data0 = display.Display().screen().root.query_pointer()._data
sample0 = Sample(data0['root_x'], data0['root_y'], time.time()

while LOOP_CONDITIONAL:
    data1 = display.Display().screen().root.query_pointer()._data
    sample1 = Sample(data1['root_x'], data1['root_y'], time.time()

    print 'Your mouse is moving at {} miles per hour'.format(calculate_speed(sample0, sample1))

    sample0 = sample1
BenTrofatter
  • 2,148
  • 1
  • 13
  • 13
  • There must surely be some way to get the DPI and dynamically calculate the ratio. – Janus Troelsen Aug 01 '11 at 20:59
  • I'd imagine you can get it from whatever library is being used to get the pixel coordinates, but I have no idea what krisdigitx is using, so figured it'd be best to leave it open. – BenTrofatter Aug 02 '11 at 21:40
  • @OlduvaiHand: how do i find out the pixel ratio of my dell xps 17inch, btw where can i get more info about pixel mile ratio..thanks.. – krisdigitx Aug 05 '11 at 10:46
  • If this is just a personal project, and you only care about the code working on your machine, just take your screen resolution and divide by the dimensions of the monitor. That'll give you pixels/inch = PPI. Then you just have to convert the bottom term into miles. So pixels/mile is going to be PPI / (12*5280), where 12 is the number of inches in a foot and 5280 is the number of feet in a mile. – BenTrofatter Aug 05 '11 at 20:06
0

I don't know which library you're using but I would use pygame.mouse.get_rel() to calculate mouse speed, it would be something easy.

BrainStorm
  • 2,036
  • 1
  • 16
  • 23