diff --git a/.classpath b/.classpath index 0f640cf..509575b 100644 --- a/.classpath +++ b/.classpath @@ -14,5 +14,6 @@ + diff --git a/src/Cursor.java b/src/Cursor.java index aa58899..ee4b30b 100644 --- a/src/Cursor.java +++ b/src/Cursor.java @@ -26,7 +26,6 @@ public class Cursor { public static final int MAXIMUM_CLICK_LENGTH = 230; private Robot robot; - private Randomizer randomizer; private Random random; private ArrayList> cursorPathsByDistance; @@ -36,7 +35,6 @@ public class Cursor { initializeCursorPathsByDistanceFromFile(Paths.CURSOR_COORDINATES_FILE_PATH); robot = new Robot(); - randomizer = new Randomizer(); random = new Random(); } @@ -72,11 +70,11 @@ public class Cursor { // TODO: make sure these are reasonable private int getRandomClickLength() { - return randomizer.nextGaussianWithinRange(MINIMUM_CLICK_LENGTH, MAXIMUM_CLICK_LENGTH); + return Randomizer.nextGaussianWithinRange(MINIMUM_CLICK_LENGTH, MAXIMUM_CLICK_LENGTH); } private int getRandomClickReleaseLength() { - return randomizer.nextGaussianWithinRange(MINIMUM_CLICK_LENGTH + 5, MAXIMUM_CLICK_LENGTH + 10); + return Randomizer.nextGaussianWithinRange(MINIMUM_CLICK_LENGTH + 5, MAXIMUM_CLICK_LENGTH + 10); } // END @@ -125,8 +123,8 @@ public class Cursor { } private Point getRandomPointInBoundingRectangle(Rectangle boundingRectangle) { - int x = randomizer.nextGaussianWithinRange(boundingRectangle.x, boundingRectangle.x + boundingRectangle.width); - int y = randomizer.nextGaussianWithinRange(boundingRectangle.y, boundingRectangle.y + boundingRectangle.height); + int x = Randomizer.nextGaussianWithinRange(boundingRectangle.x, boundingRectangle.x + boundingRectangle.width); + int y = Randomizer.nextGaussianWithinRange(boundingRectangle.y, boundingRectangle.y + boundingRectangle.height); return new Point(x, y); } @@ -165,9 +163,9 @@ public class Cursor { CursorPath cursorPathWithDistanceSet = chooseCursorPathToFollowBasedOnDistance(distanceToMoveCursor); CursorPath cursorPathWithDistanceAndAngleSet = cursorPathWithDistanceSet.getRotatedCopyOfCursorPath(angleToRotateCursorPathTo); - // TODO: Add randomization by parabola or similar - // CursorPath randomizedCursorPath = cursorPathWithDistanceAndAngleSet.getCopyOfCursorPathTransformedByParabola(); - followCursorPath(cursorPathWithDistanceAndAngleSet, startingPoint); + CursorPath cursorPathTransformed = cursorPathWithDistanceAndAngleSet.getCopyOfCursorPathTransformedByParabola(); + + followCursorPath(cursorPathTransformed, startingPoint); } public int getDistanceBetweenPoints(Point startingPoint, Point goalPoint) { @@ -243,12 +241,12 @@ public class Cursor { private Point randomizePoint(Point goalPoint, int xTolerance, int yTolerance) { Randomizer randomizer = new Randomizer(); - return new Point(goalPoint.x + randomizer.nextGaussianWithinRange(-xTolerance, xTolerance), goalPoint.y + randomizer.nextGaussianWithinRange(-yTolerance, yTolerance)); + return new Point(goalPoint.x + Randomizer.nextGaussianWithinRange(-xTolerance, xTolerance), goalPoint.y + Randomizer.nextGaussianWithinRange(-yTolerance, yTolerance)); } private Point randomizePoint(Point goalPoint, int xToleranceLeft, int xToleranceRight, int yTolerance) { Randomizer randomizer = new Randomizer(); - return new Point(goalPoint.x + randomizer.nextGaussianWithinRange(-xToleranceLeft, xToleranceRight), goalPoint.y + randomizer.nextGaussianWithinRange(-yTolerance, yTolerance)); + return new Point(goalPoint.x + Randomizer.nextGaussianWithinRange(-xToleranceLeft, xToleranceRight), goalPoint.y + Randomizer.nextGaussianWithinRange(-yTolerance, yTolerance)); } public void displayCursorPaths() { diff --git a/src/CursorPath.java b/src/CursorPath.java index ba7a6ee..6ad93ca 100644 --- a/src/CursorPath.java +++ b/src/CursorPath.java @@ -22,7 +22,6 @@ public class CursorPath { this.randomizer = new Randomizer(); } - // TODO: refactor public CursorPath(ArrayList cursorPoints, boolean setInitializiationOff) { this.cursorPoints = cursorPoints; @@ -74,15 +73,14 @@ public class CursorPath { return new CursorPath(rotatedCursorPoints, true); } - /*public CursorPath getCopyOfCursorPathTransformedByParabola() { - double[] parabolaEquation = randomizer.generateParabolaEquation(this.getCursorPathDistance()); + public CursorPath getCopyOfCursorPathTransformedByParabola() { + double[] parabolaEquation = PathTransformer.generateParabolaEquation(this.getCursorPathDistance()); ArrayList transformedCursorPoints = new ArrayList(); for (CursorPoint cursorPoint : this.cursorPoints) { - transformedCursorPoints.add(cursorPoint.getCursorPointTransformedBy(parabolaEquation)); + transformedCursorPoints.add(cursorPoint.getCursorPointTransformedByParabola(parabolaEquation)); } - return new CursorPath(transformedCursorPoints, true); - - }*/ + return new CursorPath(transformedCursorPoints, true); + } private int calculateCursorPathTimespan() { int sumPathTimespanMilliseconds = 0; diff --git a/src/CursorPoint.java b/src/CursorPoint.java index 594eb66..9feddb9 100644 --- a/src/CursorPoint.java +++ b/src/CursorPoint.java @@ -34,10 +34,12 @@ public class CursorPoint { return (new CursorPoint(rotatedX, rotatedY, delay)); } - public CursorPoint getCursorPointTransformedBy(double[] parabolaEquation) { - int rotatedX = (int) 5; - int rotatedY = (int) 5; - return (new CursorPoint(rotatedX, rotatedY, delay)); + public CursorPoint getCursorPointTransformedByParabola(double[] parabolaEquation) { + double transformationFactor = PathTransformer.getParabolaHeightAtPoint(parabolaEquation, this.getDistanceFromOrigin()); + int transformedX = (int) (transformationFactor * this.x); + int transformedY = (int) (transformationFactor * this.y); + int transformedDelay = (int) (transformationFactor * this.delay); + return (new CursorPoint(transformedX, transformedY, transformedDelay)); } public CursorPoint getCursorPointWithNewDelay(int delay) { diff --git a/src/PathTransformer.java b/src/PathTransformer.java new file mode 100644 index 0000000..a61a18e --- /dev/null +++ b/src/PathTransformer.java @@ -0,0 +1,53 @@ +import java.awt.Point; +import java.awt.geom.Point2D; + +import Jama.Matrix; + +public class PathTransformer { + + private static Point2D generatePeakForTransformationParabola(int pathDistance) { + double maxTransformationScale = 0.20; + double peakX = Randomizer.nextGaussianDoubleWithinRange(pathDistance / 3, 2 * pathDistance / 3); + double peakY = Randomizer.nextGaussianDoubleWithinRange(1 - maxTransformationScale, 1 + maxTransformationScale); + return new Point2D.Double(peakX, peakY); + } + + public static double[] generateParabolaEquation(int pathDistance) { + Point2D p1 = new Point2D.Double(0, 1); + Point2D p2 = generatePeakForTransformationParabola(pathDistance); + Point2D p3 = new Point2D.Double(pathDistance, 1); + return generateEquationForTransformationParabola(p1, p2, p3); + } + + private static double[] generateEquationForTransformationParabola(Point2D p1, Point2D p2, Point2D p3) { + if (p1.getX() == p2.getX() || p1.getX() == p3.getX() || p2.getX() == p3.getX()) { + double[] equation = {0.0, 0.0, 1.0}; + return equation; + } + double[][] lhsArray = {{0, 0, 1}, {p2.getX() * p2.getX(), p2.getX(), 1}, {p3.getX() * p3.getX(), p3.getX(), 1}}; + double[] rhsArray = {p1.getY(), p2.getY(), p3.getY()}; + Matrix lhs = new Matrix(lhsArray); + Matrix rhs = new Matrix(rhsArray, 3); + + System.out.println("(" + p1.getX() + "," + p1.getY() + "), (" + p2.getX() + "," + p2.getY() + "), (" + p3.getX() + "," + p3.getY() + ")"); + + Matrix ans = lhs.solve(rhs); + /*System.out.println("x = " + ans.get(0, 0)); + System.out.println("y = " + ans.get(1, 0)); + System.out.println("z = " + ans.get(2, 0));*/ + + double[] equation = {ans.get(0, 0), ans.get(1, 0), ans.get(2, 0)}; + return equation; + } + + public static double getParabolaHeightAtPoint(double[] parabolaEquation, double x) { + return (parabolaEquation[0] * x * x + parabolaEquation[1] * x + parabolaEquation[2]); + } + + public static void main(String[] args) { + Point2D p1 = new Point2D.Double(0, 1); + Point2D p3 = new Point2D.Double(200, 1); + Point2D p2 = generatePeakForTransformationParabola(200); + generateEquationForTransformationParabola(p1, p2, p3); + } +} diff --git a/src/Randomizer.java b/src/Randomizer.java index e5c9b2f..259ab44 100644 --- a/src/Randomizer.java +++ b/src/Randomizer.java @@ -5,6 +5,10 @@ import java.util.Random; public class Randomizer { public static int nextGaussianWithinRange(double rangeBegin, double rangeEnd) { + return (int) nextGaussianDoubleWithinRange(rangeBegin, rangeEnd); + } + + public static double nextGaussianDoubleWithinRange(double rangeBegin, double rangeEnd) { Random random = new Random(); double rangeMean = (rangeEnd + rangeBegin) / 2.0; double rangeSTD = (rangeEnd - rangeMean) / 3.0; @@ -13,12 +17,6 @@ public class Randomizer { while (result > rangeEnd || result < rangeBegin) { result = random.nextGaussian() * rangeSTD + rangeMean; } - return (int) result; - } - public static Point generatePeakForTransformationParabola(int pathDistance) { - double maxTransformationScale = 0.2; - int peakX = nextGaussianWithinRange(0, pathDistance); - int peakY = nextGaussianWithinRange(0, pathDistance * maxTransformationScale); - return new Point(peakX, peakY); + return result; } } diff --git a/target/classes/Cursor.class b/target/classes/Cursor.class index 809b9bf..aad5c08 100644 Binary files a/target/classes/Cursor.class and b/target/classes/Cursor.class differ diff --git a/target/classes/CursorPath.class b/target/classes/CursorPath.class index 140199b..1acd8a4 100644 Binary files a/target/classes/CursorPath.class and b/target/classes/CursorPath.class differ diff --git a/target/classes/CursorPoint.class b/target/classes/CursorPoint.class index 9493941..a88c33d 100644 Binary files a/target/classes/CursorPoint.class and b/target/classes/CursorPoint.class differ diff --git a/target/classes/PathTransformer.class b/target/classes/PathTransformer.class new file mode 100644 index 0000000..d62fa82 Binary files /dev/null and b/target/classes/PathTransformer.class differ diff --git a/target/classes/Randomizer.class b/target/classes/Randomizer.class index cfd3bb6..6472d22 100644 Binary files a/target/classes/Randomizer.class and b/target/classes/Randomizer.class differ