← Back to team overview

sikuli-driver team mailing list archive

Re: [Question #692019]: [request] Randomized mouse route from A to B?

 

Question #692019 on Sikuli changed:
https://answers.launchpad.net/sikuli/+question/692019

RaiMan posted a new comment:
Here you have a first draft to play with:

The code is taken from github-bezmouse and adapted to the use with
SikuliX.

from random import randint, choice
from math import ceil

def pascal_row(n):
  # This returns the nth row of Pascal's Triangle
  result = [1]
  x, numerator = 1, n
  for denominator in range(1, n//2+1):
    # print(numerator,denominator,x)
    x *= numerator
    x /= denominator
    result.append(x)
    numerator -= 1
  if n&1 == 0:
    # n is even
    result.extend(reversed(result[:-1]))
  else:
    result.extend(reversed(result))
  return result

def make_bezier(xys):
  # xys should be a sequence of 2-tuples (Bezier control points)
  n = len(xys)
  combinations = pascal_row(n - 1)
  def bezier(ts):
    # This uses the generalized formula for bezier curves
    # http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Generalization
    result = []
    for t in ts:
      tpowers = (t**i for i in range(n))
      upowers = reversed([(1-t)**i for i in range(n)])
      coefs = [c*a*b for c, a, b in zip(combinations, tpowers, upowers)]
      result.append(
        list(sum([coef*p for coef, p in zip(coefs, ps)]) for ps in zip(*xys)))
    return result
  return bezier

def mouse_bez(init_pos, fin_pos, deviation, speed):
  
  #time parameter
  ts = [t/(speed * 100.0) for t in range(speed * 101)]

  #bezier centre control points between (deviation / 2) and (deviation) of travel distance, plus or minus at random
  control_1 = (init_pos[0] + choice((-1, 1)) * abs(ceil(fin_pos[0]) - ceil(init_pos[0])) * 0.01 * randint(deviation / 2, deviation),
               init_pos[1] + choice((-1, 1)) * abs(ceil(fin_pos[1]) - ceil(init_pos[1])) * 0.01 * randint(deviation / 2, deviation)
               )
  control_2 = (init_pos[0] + choice((-1, 1)) * abs(ceil(fin_pos[0]) - ceil(init_pos[0])) * 0.01 * randint(deviation / 2, deviation),
               init_pos[1] + choice((-1, 1)) * abs(ceil(fin_pos[1]) - ceil(init_pos[1])) * 0.01 * randint(deviation / 2, deviation)
               )

  xys = [init_pos, control_1, control_2, fin_pos]
  
  bezier = make_bezier(xys)
  points = bezier(ts)

  return points

def mouseMoveTo(point):
    x = point[0]
    y = point[1]
    target = Location(x,y)
    if (SCREEN.contains(target)):
        Mouse.move(Location(x, y))

def mouseMoveRandom(reg, deviation, speed):
    here = Mouse.at()
    
    x_coord = reg.x + randint(0, reg.w)
    y_coord = reg.y + randint(0, reg.h)
    
    curve = mouse_bez((here.x, here.y), (x_coord, y_coord), deviation, speed)

    #print curve

    previous = Location(0,0)
    for point in curve:
        lPoint = Location(point[0], point[1])
        if previous.grow(1).contains(lPoint):
            continue;
        previous = lPoint
        mouseMoveTo(point)

# ----------- main script
Settings.MoveMouseDelay = 0
Mouse.move(getBottomRight().offset(-300, -300))
mouseMoveRandom(Region(0+80, 80, 10, 10), 50, 50)

-- 
You received this question notification because your team Sikuli Drivers
is an answer contact for Sikuli.