I originally posted this to code review, not knowing incomplete code was off-topic and was pointed to post here. I don't believe this question is a good fit for stack overflow because the code I currently have works, I'm just not happy with it.

I'm creating a java class to automate simple tasks on my computer. The java.awt.Robot class already comes with most functions I need. Its mouseMove function will move the mouse instantly to a point, but since a human doesn't instantly move to a point I created a function that will drag my mouse between two points over a duration of time.

My function is fixed at iterating at 1/30th of a second. I used Velocity = Distance / Time equation to get how much the mouse should move every iteration, and used the Robot mouseMove function to actually move the mouse.

I have two issues with my function:

  1. A human doesn't move to a point in a straight line, they usually curve in a positive arc no matter what direction. I'm not sure on how I should to change my algorithm to implement that.

  2. I used Thread.sleep(33) to get roughly a 1/30th iteration time for the for loop, and multiplied time by 30 to get the correct amount of iterations. I'm wasting CPU sleeping and would rather not sleep at all but I'm not sure how to calculate time since the loop can go at whatever speed it wants.

    package com;
    import java.awt.AWTException;
    import java.awt.Point;
    import java.awt.Robot;
    
    public class Tools {
        private Robot robot;
    
        public Tools() {
            try {
                robot = new Robot();
            } catch (AWTException e) {
                e.printStackTrace();
            }
        }
    
        //assumes the for loop will iterate at 30th of a second for an accurate time
        public void drag (Point p1, Point p2, double time) {
            try {
                //t = time * 30 to get correct amount of iterations
                for (long t = (long)(time * 30); t > 0; t--) {
                    p1.x += (p2.x - p1.x) / t;
                    p1.y += (p2.y - p1.y) / t;
                    robot.mouseMove(p1.x, p1.y);
                    //sleep to maintain 1/30th of a second iteration
                    Thread.sleep(33);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } 
        }
    }
    
  • 2
    Why does the realism of the mouse movement matter if the goal is simply to automate tasks that involve clicking? – Ixrec Sep 15 '15 at 22:44
  • 1
    Is the goal to try to avoid bot detection algorithms, e.g. to automate actions on an online game? – Carson63000 Sep 15 '15 at 22:48
  • 1
    No, it was originally for test automation of a website. I just think it's an interesting problem now, because I couldn't solve how to correctly arc it. – anonamousUsername Sep 16 '15 at 1:12
  • For test automation realism is out of topic. But a quadratic Bezier curve should do the job. You probably even could ignore most of the 30 points pers second. – mgoeminne Sep 16 '15 at 5:41
  • 1
    I looked into the Bezier Curve, and solved both of my problems thank you so much! – anonamousUsername Sep 19 '15 at 21:24

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.