Jump to content
Frequently Asked Questions
  • Are you not able to open the client? Try following our getting started guide
  • Still not working? Try downloading and running JarFix
  • Help! My bot doesn't do anything! Enable fresh start in client settings and restart the client
  • How to purchase with PayPal/OSRS/Crypto gold? You can purchase vouchers from other users
  • Kochanek-Bartels spline mouse algorithm for dreambot


    Deep Slayer

    Recommended Posts

    import org.dreambot.api.input.Mouse;
    import org.dreambot.api.input.event.impl.mouse.MouseButton;
    import org.dreambot.api.input.mouse.algorithm.MouseAlgorithm;
    import org.dreambot.api.input.mouse.destination.AbstractMouseDestination;
    import org.dreambot.api.methods.Calculations;
    import org.dreambot.api.utilities.Logger;
    
    import java.awt.*;
    import java.util.Random;
    
    /**
     * Open source Mouse Algorithm using Kochanek-Bartels splines
     */
    public class KochanekBartelsMouse implements MouseAlgorithm {
        private final double tension;
        private final double bias;
        private final double continuity;
        private Random random = new Random();
    
        public KochanekBartelsMouse(double tension, double bias, double continuity) {
            this.tension = tension;
            this.bias = bias;
            this.continuity = continuity;
        }
    
        @Override
        public boolean handleMovement(AbstractMouseDestination abstractMouseDestination) {
            Point suitPos = abstractMouseDestination.getSuitablePoint();
            mouseMovement(suitPos);
            return distance(Mouse.getPosition(), suitPos) < 2;
        }
    
        @Override
        public boolean handleClick(MouseButton mouseButton) {
            return Mouse.getDefaultMouseAlgorithm().handleClick(mouseButton);
        }
    
        public static void sleep(int min, int max) {
            try {
                Thread.sleep(Calculations.random(min, max));
            } catch (InterruptedException e) {
                Logger.log(e.getMessage());
            }
        }
    
        public static void sleep(int ms) {
            try {
                Thread.sleep(ms);
            } catch (InterruptedException e) {
                Logger.log(e.getMessage());
            }
        }
    
        /**
         * Enhanced mouse movement using Kochanek-Bartels splines
         *
         * @param point The destination point
         */
        public void mouseMovement(Point point) {
            Point curPos = Mouse.getPosition();
            moveMouseSpline(curPos, point); // Directly move to the target point
        }
    
        /**
         * Generate control points for Kochanek Bartels spline
         *
         * @param start The start point
         * @param end   The end point
         * @return Array of control points
         */
        private Point[] generateControlPoints(Point start, Point end) {
            Point[] controlPoints = new Point[4];
            controlPoints[0] = start;
            controlPoints[3] = end;
    
            int midX = (start.x + end.x) / 2;
            int midY = (start.y + end.y) / 2;
    
            // Adjusting control points to create more noticeable curves
            controlPoints[1] = new Point(midX + random.nextInt(200) - 100, midY + random.nextInt(200) - 100);
            controlPoints[2] = new Point(midX + random.nextInt(200) - 100, midY + random.nextInt(200) - 100);
    
            return controlPoints;
        }
    
        /**
         * Move mouse using a Kochanek Bartels spline
         *
         * @param start The start point
         * @param end   The end point
         */
        private void moveMouseSpline(Point start, Point end) {
            Point[] controlPoints = generateControlPoints(start, end);
            int steps = Calculations.random(50, 100); // Increase steps for smoother curves
    
            for (int i = 0; i <= steps; i++) {
                double t = (double) i / (double) steps;
                Point p = kochanekBartelsSpline(controlPoints, t);
                Mouse.hop(p);
    
                try {
                    Thread.sleep(Calculations.random(5, 15));
                } catch (InterruptedException e) {
                    Logger.log(e.getMessage());
                }
            }
        }
    
        /**
         * Calculate a point on a Kochanek Bartels spline
         *
         * @param points The control points
         * @param t      The parameter t (0 <= t <= 1)
         * @return The point on the spline at parameter t
         */
        private Point kochanekBartelsSpline(Point[] points, double t) {
            double t2 = t * t;
            double t3 = t2 * t;
    
            double h1 = 2 * t3 - 3 * t2 + 1;
            double h2 = -2 * t3 + 3 * t2;
            double h3 = t3 - 2 * t2 + t;
            double h4 = t3 - t2;
    
            Point p0 = points[0];
            Point p1 = points[3];
            Point p2 = points[1];
            Point p3 = points[2];
    
            double m0x = (1 - tension) * (1 + bias) * (1 + continuity) * (p2.x - p0.x) / 2 +
                    (1 - tension) * (1 - bias) * (1 - continuity) * (p3.x - p1.x) / 2;
            double m0y = (1 - tension) * (1 + bias) * (1 + continuity) * (p2.y - p0.y) / 2 +
                    (1 - tension) * (1 - bias) * (1 - continuity) * (p3.y - p1.y) / 2;
            double m1x = (1 - tension) * (1 - bias) * (1 + continuity) * (p3.x - p1.x) / 2 +
                    (1 - tension) * (1 + bias) * (1 - continuity) * (p3.x - p2.x) / 2;
            double m1y = (1 - tension) * (1 - bias) * (1 + continuity) * (p3.y - p1.y) / 2 +
                    (1 - tension) * (1 + bias) * (1 - continuity) * (p3.y - p2.y) / 2;
    
            int x = (int) (h1 * p0.x + h2 * p1.x + h3 * m0x + h4 * m1x);
            int y = (int) (h1 * p0.y + h2 * p1.y + h3 * m0y + h4 * m1y);
    
            return new Point(x, y);
        }
    
        public double distance(Point p1, Point p2) {
            return Math.sqrt((p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x));
        }
    }
    

    KochanekBartelsMouse.java

    Link to comment
    Share on other sites

    Posted (edited)
    Mouse.setMouseAlgorithm(new KochanekBartelsMouse(5,0,0.1));

    don't forget to add this line in your onStart() method and play around with the 3 argument - tension, bias & continuity

    enjoy this algorithm that should be free to all

    Edited by Deep Slayer
    Link to comment
    Share on other sites

    Upated to use Perlin noise to generate control points, plenty of variables to adjust, have fun

     

    import org.dreambot.api.input.Mouse;
    import org.dreambot.api.input.event.impl.mouse.MouseButton;
    import org.dreambot.api.input.mouse.algorithm.MouseAlgorithm;
    import org.dreambot.api.input.mouse.destination.AbstractMouseDestination;
    import org.dreambot.api.methods.Calculations;
    import org.dreambot.api.utilities.Logger;
    
    import java.awt.*;
    import java.util.Random;
    
    /**
     * Open source Mouse Algorithm using Kochanek-Bartels splines
     */
    public class KochanekBartelsMouse implements MouseAlgorithm {
        private final double tension;
        private final double bias;
        private final double continuity;
        private Random random = new Random();
    
        public KochanekBartelsMouse(double tension, double bias, double continuity) {
            this.tension = tension;
            this.bias = bias;
            this.continuity = continuity;
        }
    
        @Override
        public boolean handleMovement(AbstractMouseDestination abstractMouseDestination) {
            Point suitPos = abstractMouseDestination.getSuitablePoint();
            mouseMovement(suitPos);
            return distance(Mouse.getPosition(), suitPos) < 2;
        }
    
        @Override
        public boolean handleClick(MouseButton mouseButton) {
            return Mouse.getDefaultMouseAlgorithm().handleClick(mouseButton);
        }
    
        public static void sleep(int min, int max) {
            try {
                Thread.sleep(Calculations.random(min, max));
            } catch (InterruptedException e) {
                Logger.log(e.getMessage());
            }
        }
    
        public static void sleep(int ms) {
            try {
                Thread.sleep(ms);
            } catch (InterruptedException e) {
                Logger.log(e.getMessage());
            }
        }
    
        /**
         * Enhanced mouse movement using Kochanek Bartels splines
         *
         * @param point The destination point
         */
        public void mouseMovement(Point point) {
            Point curPos = Mouse.getPosition();
            moveMouseSpline(curPos, point); // Directly move to the target point
        }
    
        /**
         * Generate control points for Kochanek Bartels spline
         *
         * @param start The start point
         * @param end   The end point
         * @return Array of control points
         */
        private Point[] generateControlPoints(Point start, Point end) {
            Point[] controlPoints = new Point[4];
            controlPoints[0] = start;
            controlPoints[3] = end;
    
            double distance = distance(start, end);
            int maxOffset = (int) (distance / 4); // adjust this to control the curve complexity
    
            int midX = (start.x + end.x) / 2;
            int midY = (start.y + end.y) / 2;
    
            // Using Perlin noise to create more complex control points
            double noise1 = perlinNoise(random.nextDouble(), random.nextDouble());
            double noise2 = perlinNoise(random.nextDouble(), random.nextDouble());
            double angle = Math.atan2(end.y - start.y, end.x - start.x);
            double offsetAngle = Math.PI / 10; // adjust this angle for different curve shapes
    
            controlPoints[1] = new Point(midX + (int) (Math.cos(angle - offsetAngle) * maxOffset + noise1 * maxOffset), midY + (int) (Math.sin(angle - offsetAngle) * maxOffset + noise1 * maxOffset));
            controlPoints[2] = new Point(midX + (int) (Math.cos(angle + offsetAngle) * maxOffset + noise2 * maxOffset), midY + (int) (Math.sin(angle + offsetAngle) * maxOffset + noise2 * maxOffset));
    
            return controlPoints;
        }
    
        /**
         * Move mouse using a Kochanek Bartels spline
         *
         * @param start The start point
         * @param end   The end point
         */
        private void moveMouseSpline(Point start, Point end) {
            Point[] controlPoints = generateControlPoints(start, end);
            int steps = Calculations.random(50, 100); // Increase steps for smoother curves
    
            for (int i = 0; i <= steps; i++) {
                double t = (double) i / (double) steps;
                Point p = kochanekBartelsSpline(controlPoints, t);
                Mouse.hop(p);
    
                try {
                    Thread.sleep(Calculations.random(5, 15));
                } catch (InterruptedException e) {
                    Logger.log(e.getMessage());
                }
            }
        }
    
        /**
         * Calculate a point on a Kochanek Bartels spline
         *
         * @param points The control points
         * @param t      The parameter t (0 <= t <= 1)
         * @return The point on the spline at parameter t
         */
        private Point kochanekBartelsSpline(Point[] points, double t) {
            double t2 = t * t;
            double t3 = t2 * t;
    
            double h1 = 2 * t3 - 3 * t2 + 1;
            double h2 = -2 * t3 + 3 * t2;
            double h3 = t3 - 2 * t2 + t;
            double h4 = t3 - t2;
    
            Point p0 = points[0];
            Point p1 = points[3];
            Point p2 = points[1];
            Point p3 = points[2];
    
            double m0x = (1 - tension) * (1 + bias) * (1 + continuity) * (p2.x - p0.x) / 2 +
                    (1 - tension) * (1 - bias) * (1 - continuity) * (p3.x - p1.x) / 2;
            double m0y = (1 - tension) * (1 + bias) * (1 + continuity) * (p2.y - p0.y) / 2 +
                    (1 - tension) * (1 - bias) * (1 - continuity) * (p3.y - p1.y) / 2;
            double m1x = (1 - tension) * (1 - bias) * (1 + continuity) * (p3.x - p1.x) / 2 +
                    (1 - tension) * (1 + bias) * (1 - continuity) * (p3.x - p2.x) / 2;
            double m1y = (1 - tension) * (1 - bias) * (1 + continuity) * (p3.y - p1.y) / 2 +
                    (1 - tension) * (1 + bias) * (1 - continuity) * (p3.y - p2.y) / 2;
    
            int x = (int) (h1 * p0.x + h2 * p1.x + h3 * m0x + h4 * m1x);
            int y = (int) (h1 * p0.y + h2 * p1.y + h3 * m0y + h4 * m1y);
    
            return new Point(x, y);
        }
    
        /**
         * Simple Perlin noise implementation
         *
         * @param x The x coordinate
         * @param y The y coordinate
         * @return The Perlin noise value
         */
        private double perlinNoise(double x, double y) {
            return Math.sin(2 * Math.PI * x) * Math.cos(2 * Math.PI * y);
        }
    
        public double distance(Point p1, Point p2) {
            return Math.sqrt((p2.y - p1.y) * (p2.y - p1.y) + (p2.x - p1.x) * (p2.x - p1.x));
        }
    }
    
    Link to comment
    Share on other sites

    It would be interesting if you added some information of what is a Kochanek-Bartels spline and what each constant means for those who do not know.
    I know most people will only copy-paste this into their projects, but it is very important to understand what the algorithm does and why, so you can refactor it to your needs.
    I'll leave some references here for anyone who gets interested.

    Nice contribution, and nice spoonfeed for those who are starting!
     

     

    Extra tips: you can tweak a lot on this type of spline when you get to understand its constants, implement this with the Shannon formulation of Fitts' Law for fun, or adjust its randomness however you like. Draw cursor path to debug it.

    Link to comment
    Share on other sites

    You can assign values to Tension, Bias and Continuity in the constructor when you instantiate the mouse algorithm, it should be there in my 2nd post.

    1. Tension (T)

    Definition: Tension controls the tightness of the curve.

    Effect:

    Higher tension values pull the curve tighter toward the control points, making the curve sharper and less smooth.

    Lower tension values make the curve more relaxed and looser, making the curve smoother and more wavy.

     

    2. Continuity (C)

    Definition: Continuity affects the smoothness of the transition between curve segments.

    Effect:

    Positive continuity values make the curve segments blend more smoothly into each other.

    Negative continuity values create a more abrupt change in direction between segments, causing the curve to have sharper transitions.

     

    3. Bias (B)

    Definition: Bias determines the curve’s tendency to lean toward one side of the control points.

    Effect:

    Positive bias values pull the curve toward the next control point.

    Negative bias values pull the curve toward the previous control point.

    Link to comment
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now
    ×
    ×
    • Create New...

    Important Information

    We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.