diff --git a/bin/Cursor.class b/bin/Cursor.class index bd310c6..be322cf 100644 Binary files a/bin/Cursor.class and b/bin/Cursor.class differ diff --git a/bin/CursorPath.class b/bin/CursorPath.class index 446e630..21b1b10 100644 Binary files a/bin/CursorPath.class and b/bin/CursorPath.class differ diff --git a/bin/CursorPathTest.class b/bin/CursorPathTest.class new file mode 100644 index 0000000..bb9a407 Binary files /dev/null and b/bin/CursorPathTest.class differ diff --git a/bin/CursorPoint.class b/bin/CursorPoint.class index a982697..76c36cc 100644 Binary files a/bin/CursorPoint.class and b/bin/CursorPoint.class differ diff --git a/bin/CursorPointTest.class b/bin/CursorPointTest.class new file mode 100644 index 0000000..5f85cbb Binary files /dev/null and b/bin/CursorPointTest.class differ diff --git a/bin/MousePathTest.class b/bin/MousePathTest.class deleted file mode 100644 index a09caa1..0000000 Binary files a/bin/MousePathTest.class and /dev/null differ diff --git a/bin/MouseTest.class b/bin/MouseTest.class deleted file mode 100644 index f196b76..0000000 Binary files a/bin/MouseTest.class and /dev/null differ diff --git a/bin/Randomizer.class b/bin/Randomizer.class index 864f23a..6485227 100644 Binary files a/bin/Randomizer.class and b/bin/Randomizer.class differ diff --git a/src/Cursor.java b/src/Cursor.java index c3a20c7..f98833b 100644 --- a/src/Cursor.java +++ b/src/Cursor.java @@ -27,7 +27,7 @@ public class Cursor { private Robot robot; - private Random random = new Random(); + private Randomizer randomizer; private ArrayList> cursorPathsByDistance; @@ -36,7 +36,7 @@ public class Cursor { initializeCursorPathsByDistanceFromFile("/home/dpapp/GhostMouse/coordinates.txt"); robot = new Robot(); - random = new Random(); + randomizer = new Randomizer(); } private void initializeCursorPathsByDistanceFromFile(String path) { @@ -72,7 +72,7 @@ public class Cursor { // TODO: make sure these are reasonable private int getRandomClickLength() { - return random.nextInt(MAXIMUM_CLICK_LENGTH - MINIMUM_CLICK_LENGTH) + MINIMUM_CLICK_LENGTH; + return randomizer.nextGaussianWithinRange(MINIMUM_CLICK_LENGTH, MAXIMUM_CLICK_LENGTH); } public void leftClickCursor() throws InterruptedException { @@ -114,12 +114,12 @@ public class Cursor { } public void moveCursorToCoordinates(Point goalPoint) throws InterruptedException { - Point startingCursorPoint = getCurrentCursorPoint(); - int distanceToMoveCursor = calculateDistanceBetweenPoints(startingCursorPoint, goalPoint); + Point startingPoint = getCurrentCursorPoint(); + int distanceToMoveCursor = (int) startingPoint.distance(goalPoint); if (distanceToMoveCursor == 0) { return; } - double angleToMoveCursor = calculateThetaBetweenPoints(startingCursorPoint, goalPoint); + double angleToMoveCursor = getThetaBetweenPoints(startingPoint, goalPoint); // TODO: check if exists CursorPath cursorPathToFollow = chooseCursorPathToFollowBasedOnDistance(distanceToMoveCursor); @@ -127,20 +127,20 @@ public class Cursor { followCursorPath(startingCursorPoint, angleToTranslatePathBy, cursorPathToFollow); } + + //TODO: fix + private double getThetaBetweenPoints(Point startingPoint, Point goalPoint) { + return Math.atan2(startingPoint.x * goalPoint.y, 1.0 * goalPoint.x); + } + private void followCursorPath(Point startingCursorPoint, double angleToTranslatePathBy, CursorPath cursorPathToFollow) throws InterruptedException { for (CursorPoint untranslatedCursorPoint : cursorPathToFollow.getCursorPathPoints()) { Point translatedPointToClick = translatePoint(startingCursorPoint, angleToTranslatePathBy, untranslatedCursorPoint); robotMouseMove(translatedPointToClick); - Thread.sleep(untranslatedCursorPoint.postMillisecondDelay); + Thread.sleep(untranslatedCursorPoint.delay); } } - private Point translatePoint(Point startingCursorPoint, double angleToTranslateBy, CursorPoint untranslatedCursorPoint) { - int x = (int) (startingCursorPoint.x + Math.cos(angleToTranslateBy) * untranslatedCursorPoint.x - Math.sin(angleToTranslateBy) * untranslatedCursorPoint.y); - int y = (int) (startingCursorPoint.y + Math.sin(angleToTranslateBy) * untranslatedCursorPoint.x + Math.cos(angleToTranslateBy) * untranslatedCursorPoint.y); - return new Point(x, y); - } - public void robotMouseMove(Point pointToMoveCursorTo) { robot.mouseMove(pointToMoveCursorTo.x, pointToMoveCursorTo.y); } @@ -154,7 +154,7 @@ public class Cursor { double scaleFactor = getScaleFactor(newDistanceToMoveCursor, distanceToMoveCursor); ArrayList cursorPathsWithSameDistance = cursorPathsByDistance.get(newDistanceToMoveCursor); - CursorPath scaledCursorPath = cursorPathsWithSameDistance.get(random.nextInt(cursorPathsWithSameDistance.size())).getScaledCopyOfCursorPath(1.0); + CursorPath scaledCursorPath = cursorPathsWithSameDistance.get(new Random().nextInt(cursorPathsWithSameDistance.size())).getScaledCopyOfCursorPath(1.0); return scaledCursorPath; } @@ -175,24 +175,14 @@ public class Cursor { return (1.0 * newDistanceToMoveCursor / distanceToMoveCursor); } - private int calculateDistanceBetweenPoints(Point a, Point b) { - return (int) (Math.hypot(a.x - b.x, a.y - b.y)); - } - - public double calculateThetaBetweenPoints(Point a, Point b) { - return Math.atan2(1.0 * (b.y - a.y), 1.0 * (b.x - a.x)); - } public Point getCurrentCursorPoint() { return MouseInfo.getPointerInfo().getLocation(); } - private int getRandomIntSigned(int tolerance) { - return random.nextInt(tolerance) - tolerance / 2; - } - private Point randomizePoint(Point goalPoint, int xTolerance, int yTolerance) { - return new Point(goalPoint.x + getRandomIntSigned(xTolerance), goalPoint.y + getRandomIntSigned(yTolerance)); + Randomizer randomizer = new Randomizer(); + return new Point(goalPoint.x + randomizer.nextGaussianWithinRange(-xTolerance, xTolerance), goalPoint.y + randomizer.nextGaussianWithinRange(-yTolerance, yTolerance)); } public void displayCursorPaths() { diff --git a/src/CursorPath.java b/src/CursorPath.java index 682d371..b27573a 100644 --- a/src/CursorPath.java +++ b/src/CursorPath.java @@ -6,70 +6,86 @@ import java.util.ArrayList; public class CursorPath { - private ArrayList pathCursorPoints; - private int pathNumPoints; - private int pathDistance; - private double pathTheta; - private int pathTimespanMilliseconds; + private ArrayList cursorPoints; + private double theta; + private int distance; + private int timespan; public CursorPath(ArrayList cursorPoints) { - this.pathCursorPoints = copyCursorPointsWithOffset(cursorPoints); - this.pathNumPoints = cursorPoints.size(); - this.pathDistance = calculateCursorPathDistance(); - this.pathTheta = calculateCursorPathTheta(); - this.pathTimespanMilliseconds = calculateCursorPathTimespan(); + this.cursorPoints = initializePathOfCursorPoints(cursorPoints); + this.distance = calculateCursorPathDistance(); + this.theta = calculateCursorPathTheta(); + this.timespan = calculateCursorPathTimespan(); } - private ArrayList copyCursorPointsWithOffset(ArrayList cursorPoints) { - ArrayList cursorPointsCopy = new ArrayList(cursorPoints.size()); + private ArrayList initializePathOfCursorPoints(ArrayList cursorPoints) { CursorPoint startingCursorPoint = cursorPoints.get(0); + ArrayList translatedCursorPoints = getTranslatedCopyOfCursorPath(cursorPoints, startingCursorPoint); + ArrayList normalizedDelayCursorPoints = getNormalizedDelayCopyOfCursorPath(translatedCursorPoints); + return normalizedDelayCursorPoints; + } + + private ArrayList getTranslatedCopyOfCursorPath(ArrayList cursorPoints, CursorPoint cursorPointToTranslateBy) { + ArrayList offsetCursorPath = new ArrayList(); for (CursorPoint cursorPoint : cursorPoints) { - cursorPointsCopy.add(getOffsetCursorPoint(cursorPoint, startingCursorPoint)); + offsetCursorPath.add(cursorPoint.getCursorPointTranslatedBy(cursorPointToTranslateBy)); } - calculatePostMillisecondDelays(cursorPointsCopy); - return cursorPointsCopy; + return offsetCursorPath; } - private void calculatePostMillisecondDelays(ArrayList cursorPoints) { - for (int i = 1; i < cursorPoints.size(); i++) { - cursorPoints.get(i - 1).setPostMillisecondDelay(cursorPoints.get(i).postMillisecondDelay - cursorPoints.get(i - 1).postMillisecondDelay); + private ArrayList getNormalizedDelayCopyOfCursorPath(ArrayList cursorPoints) { + ArrayList normalizedDelayCursorPoints = new ArrayList(); + for (int i = 0; i < cursorPoints.size() - 1; i++) { + CursorPoint cursorPoint = cursorPoints.get(i); + CursorPoint nextCursorPoint = cursorPoints.get(i + 1); + normalizedDelayCursorPoints.add(cursorPoint.getCursorPointWithNewDelay(nextCursorPoint.delay - cursorPoint.delay)); } - cursorPoints.get(cursorPoints.size() - 1).setPostMillisecondDelay(0); + normalizedDelayCursorPoints.add(cursorPoints.get(cursorPoints.size() - 1).getCursorPointWithNewDelay(0)); + return normalizedDelayCursorPoints; + } + + + public ArrayList getScaledCopyOfCursorPath(double factorToScaleBy) { + ArrayList scaledCursorPath = new ArrayList(); + for (CursorPoint cursorPoint : this.cursorPoints) { + scaledCursorPath.add(cursorPoint.getCursorPointScaledBy(factorToScaleBy)); + } + return scaledCursorPath; } - private CursorPoint getOffsetCursorPoint(CursorPoint cursorPoint, CursorPoint offsetPoint) { - return new CursorPoint(cursorPoint.x - offsetPoint.x, cursorPoint.y - offsetPoint.y, cursorPoint.postMillisecondDelay); + public ArrayList getRotatedCopyOfCursorPath(double angleToRotateBy) { + ArrayList rotatedCursorPath = new ArrayList(); + for (CursorPoint cursorPoint : this.cursorPoints) { + rotatedCursorPath.add(cursorPoint.getCursorPointRotatedBy(angleToRotateBy)); + } + return rotatedCursorPath; } private int calculateCursorPathTimespan() { int sumPathTimespanMilliseconds = 0; - for (CursorPoint cursorPoint : this.pathCursorPoints) { - sumPathTimespanMilliseconds += cursorPoint.postMillisecondDelay; + for (CursorPoint cursorPoint : this.cursorPoints) { + sumPathTimespanMilliseconds += cursorPoint.delay; } return sumPathTimespanMilliseconds; } private int calculateCursorPathDistance() { - return (int) calculateDistanceBetweenCursorPoints(getStartingCursorPoint(), getEndingCursorPoint()); + return (int) (getStartingCursorPoint().getDistanceFrom(getEndingCursorPoint())); } private double calculateCursorPathTheta() { - CursorPoint endingCursorPoint = getEndingCursorPoint(); - return Math.atan2(1.0 * endingCursorPoint.y, 1.0 * endingCursorPoint.x); + return getStartingCursorPoint().getThetaFrom(getEndingCursorPoint()); } - private CursorPoint getStartingCursorPoint() { - return pathCursorPoints.get(0); + public CursorPoint getStartingCursorPoint() { + return this.cursorPoints.get(0); } - private CursorPoint getEndingCursorPoint() { - return pathCursorPoints.get(pathNumPoints - 1); + public CursorPoint getEndingCursorPoint() { + return this.cursorPoints.get(this.cursorPoints.size() - 1); } - private double calculateDistanceBetweenCursorPoints(CursorPoint a, CursorPoint b) { - return Math.hypot(a.x - b.x, a.y - b.y); - } public boolean isCursorPathReasonable() { return isCursorPathTimespanReasonable() && isCursorPathDistanceReasonable() && @@ -77,42 +93,35 @@ public class CursorPath { } private boolean isCursorPathTimespanReasonable() { - return (this.pathTimespanMilliseconds > 50 && this.pathTimespanMilliseconds < 400); + return (this.timespan > 50 && this.timespan < 400); } private boolean isCursorPathDistanceReasonable() { - return (this.pathDistance > 0 && this.pathDistance < 1000); + return (this.distance > 0 && this.distance < 1000); } private boolean isCursorPathNumPointsReasonable() { - return (this.pathNumPoints > 0 && this.pathNumPoints < 50); + return (this.cursorPoints.size() > 0 && this.cursorPoints.size() < 50); } public ArrayList getCursorPathPoints() { - return pathCursorPoints; + return cursorPoints; } public int getCursorPathDistance() { - return pathDistance; + return distance; } public double getCursorPathTheta() { - return pathTheta; - } - - public CursorPath getScaledCopyOfCursorPath(double scaleFactor) { - ArrayList scaledCursorPath = new ArrayList(); - for (CursorPoint cursorPoint : this.pathCursorPoints) { - scaledCursorPath.add(new CursorPoint((int) (cursorPoint.x * scaleFactor), (int) (cursorPoint.y * scaleFactor), (int) (cursorPoint.postMillisecondDelay * scaleFactor))); - } - return new CursorPath(scaledCursorPath); + return theta; } + public void displayCursorPoints() { - for (CursorPoint p : pathCursorPoints) { + for (CursorPoint p : this.cursorPoints) { p.display(); } - System.out.println("Length:" + pathNumPoints + ", Timespan:" + pathTimespanMilliseconds); + System.out.println("Number of points:" + this.cursorPoints.size() + ", Timespan:" + this.timespan); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~ End of Path ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); } } \ No newline at end of file diff --git a/src/CursorPathTest.java b/src/CursorPathTest.java new file mode 100644 index 0000000..aebfc08 --- /dev/null +++ b/src/CursorPathTest.java @@ -0,0 +1,78 @@ +import static org.junit.jupiter.api.Assertions.*; + +import java.util.ArrayList; + +import org.junit.jupiter.api.Test; + +class CursorPathTest { + + ArrayList cursorPaths; + + + @Test + void testCursorPathOffset() { + initializeCursorPath(); + + for (CursorPath cursorPath : cursorPaths) { + testCursorPathStartsAtOrigin(cursorPath); + testEndingCursorPointInCursorPathHasZeroDelay(cursorPath); + //testCursorPathLocations(cursorPath); + testCursorPathRotation(cursorPath, 15); + testCursorPathScaling(cursorPath, 1.15); + cursorPath.displayCursorPoints(); + } + } + + private void testCursorPathStartsAtOrigin(CursorPath cursorPath) { + CursorPoint startingCursorPoint = cursorPath.getStartingCursorPoint(); + assertTrue(startingCursorPoint.x == 0 && startingCursorPoint.y == 0); + } + + private void testEndingCursorPointInCursorPathHasZeroDelay(CursorPath cursorPath) { + CursorPoint endingCursorPoint = cursorPath.getEndingCursorPoint(); + assertEquals(endingCursorPoint.delay, 0); + } + + /*private void testCursorPathLocations(CursorPath cursorPath) { + + }*/ + + void testCursorPathRotation(CursorPath cursorPath, double angleToRotateBy) { + ArrayList cursorPoints = cursorPath.getCursorPathPoints(); + ArrayList rotatedCursorPoints = cursorPath.getRotatedCopyOfCursorPath(angleToRotateBy); + assertEquals(cursorPoints.size(), rotatedCursorPoints.size()); + CursorPoint startingPoint = cursorPoints.get(0); + for (int i = 1; i < cursorPoints.size(); i++) { + double originalThetaOfCursorPoint = cursorPoints.get(i).getThetaFrom(startingPoint); + double rotatedThetaOfCursorPoint = rotatedCursorPoints.get(i).getThetaFrom(startingPoint); + System.out.println(originalThetaOfCursorPoint + ", " + rotatedThetaOfCursorPoint); + assertInRangeByAbsoluteValue(originalThetaOfCursorPoint + angleToRotateBy, rotatedThetaOfCursorPoint, 3); + } + } + + void testCursorPathScaling(CursorPath cursorPath, double factorToScaleBy) { + ArrayList cursorPoints = cursorPath.getCursorPathPoints(); + ArrayList scaledCursorPoints = cursorPath.getScaledCopyOfCursorPath(factorToScaleBy); + assertEquals(cursorPoints.size(), scaledCursorPoints.size()); + CursorPoint startingPoint = cursorPoints.get(0); + for (int i = 0; i < cursorPoints.size(); i++) { + double originalDistanceOfCursorPoint = cursorPoints.get(i).getDistanceFrom(startingPoint); + double scaledDistanceOfCursorPoint = scaledCursorPoints.get(i).getDistanceFrom(startingPoint); + assertInRangeByAbsoluteValue(originalDistanceOfCursorPoint * factorToScaleBy, scaledDistanceOfCursorPoint, 3); + } + } + + void initializeCursorPath() { + CursorDataFileParser cursorDataFileParser = new CursorDataFileParser("/home/dpapp/eclipse-workspace/RunescapeAI/testfiles/cursorPathTest.txt"); + this.cursorPaths = cursorDataFileParser.getArrayListOfCursorPathsFromFile(); + + } + + void assertInRangeByRatio(double valueToTest, double expectation, double toleranceRatio) { + assertTrue((valueToTest <= (expectation * (1 + toleranceRatio))) && (valueToTest >= (expectation * (1 - toleranceRatio)))); + } + + void assertInRangeByAbsoluteValue(double valueToTest, double expectation, double toleranceAbsolute) { + assertTrue((valueToTest <= (expectation + toleranceAbsolute)) && (valueToTest >= (expectation * (1 - toleranceAbsolute)))); + } +} diff --git a/src/CursorPoint.java b/src/CursorPoint.java index d507062..9d89f21 100644 --- a/src/CursorPoint.java +++ b/src/CursorPoint.java @@ -1,20 +1,44 @@ +import java.awt.Point; + public class CursorPoint { public int x; public int y; - public int postMillisecondDelay; // how much to sleep for after moving here + public int delay; - public CursorPoint(int x, int y, int postMillisecondDelay) { + public CursorPoint(int x, int y, int delay) { this.x = x; this.y = y; - this.postMillisecondDelay = postMillisecondDelay; + this.delay = delay; } - public void setPostMillisecondDelay(int postMillisecondDelay) { - this.postMillisecondDelay = postMillisecondDelay; + public double getDistanceFrom(CursorPoint b) { + return Math.hypot(this.x - b.x, this.y - b.y); + } + + public double getThetaFrom(CursorPoint b) { + return Math.atan2(1.0 * b.y, 1.0 * b.x); + } + + public CursorPoint getCursorPointTranslatedBy(CursorPoint startingCursorPoint) { + return new CursorPoint(this.x - startingCursorPoint.x, this.y - startingCursorPoint.y, this.delay - startingCursorPoint.delay); + } + + public CursorPoint getCursorPointScaledBy(double scaleFactor) { + return (new CursorPoint((int) (this.x * scaleFactor), (int) (this.y * scaleFactor), (int) (this.delay * scaleFactor))); + } + + public CursorPoint getCursorPointRotatedBy(double angleOfRotation) { + int rotatedX = (int) (this.x + Math.cos(angleOfRotation) * this.x - Math.sin(angleOfRotation) * this.y); + int rotatedY = (int) (this.y + Math.sin(angleOfRotation) * this.x + Math.cos(angleOfRotation) * this.y); + return (new CursorPoint(rotatedX, rotatedY, this.delay)); + } + + public CursorPoint getCursorPointWithNewDelay(int delay) { + return (new CursorPoint(this.x, this.y, delay)); } public void display() { - System.out.println("Point: (" + x + "," + y + "), delay: " + postMillisecondDelay); + System.out.println("Point: (" + x + "," + y + "), delay: " + delay); } } \ No newline at end of file diff --git a/src/CursorPointTest.java b/src/CursorPointTest.java new file mode 100644 index 0000000..a7c5ba0 --- /dev/null +++ b/src/CursorPointTest.java @@ -0,0 +1,43 @@ +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class CursorPointTest { + + @Test + void testDistanceFrom() { + CursorPoint a = new CursorPoint(0, 0, 0); + CursorPoint b = new CursorPoint(3, 4, 0); + CursorPoint c = new CursorPoint(500, 750, 0); + CursorPoint d = new CursorPoint(284, 848, 0); + + assertTrue(withinRangeByRatio(a.getDistanceFrom(b), 5, 0.0001)); + assertTrue(withinRangeByRatio(a.getDistanceFrom(c), 901.387818866, 0.0001)); + assertTrue(withinRangeByRatio(a.getDistanceFrom(d), 894.293016857, 0.0001)); + assertTrue(withinRangeByRatio(b.getDistanceFrom(c), 896.395560007, 0.0001)); + assertTrue(withinRangeByRatio(c.getDistanceFrom(d), 237.191905427, 0.0001)); + } + + @Test + void testCursorPointRotation() { + CursorPoint a = new CursorPoint(0, 0, 0); + CursorPoint b = new CursorPoint(10, 0, 0); + //CursorPoint c = new CursorPoint(10, 20, 0); + CursorPoint d = a.getCursorPointRotatedBy(Math.PI / 4); + CursorPoint e = b.getCursorPointRotatedBy(Math.PI / 2); + //CursorPoint f = c.getCursorPointRotatedBy(90); + + //System.out.println(a.getThetaFrom(a)); + //System.out.println(b.getThetaFrom(a)); + assertTrue(d.x == 0 && d.y == 0); + System.out.println(e.x + ", " + e.y); + //assertTrue(e.x == 5); + + //assertTrue(withinRangeByRatio()) + } + + boolean withinRangeByRatio(double actual, double expectation, double toleranceRatio) { + return ((actual <= (expectation * (1 + toleranceRatio))) && (actual >= (expectation * (1 - toleranceRatio)))); + } + +} diff --git a/src/MousePathTest.java b/src/MousePathTest.java deleted file mode 100644 index b5c15f6..0000000 --- a/src/MousePathTest.java +++ /dev/null @@ -1,30 +0,0 @@ -import static org.junit.jupiter.api.Assertions.*; - -import java.util.ArrayList; - -import org.junit.jupiter.api.Test; - -class MousePathTest { - - - @Test - void mousePathLengthTest() { - - } - - @Test - void mousePathTimespanTest() { - - } - - @Test - void mousePathStartingPointTest() { - - } - - @Test - void mousePathEndingPointTest() { - - } - -} diff --git a/src/MouseTest.java b/src/MouseTest.java deleted file mode 100644 index f73c6d1..0000000 --- a/src/MouseTest.java +++ /dev/null @@ -1,21 +0,0 @@ -import static org.junit.jupiter.api.Assertions.*; -import java.util.ArrayList; -import org.junit.jupiter.api.Test; - -/* - * Things to test: - * - Invalid regex expression - * - Empty paths (mouse jumps) - * - Short paths - * - No input file - * - Long paths - */ - -class MouseTest { - - @Test - void testMouseLengths() { - - } - -} diff --git a/src/Randomizer.java b/src/Randomizer.java index bcdb039..4d71aa7 100644 --- a/src/Randomizer.java +++ b/src/Randomizer.java @@ -10,18 +10,20 @@ public class Randomizer { random = new Random(); } - public int nextGaussianWithinThreeSTDs(int mean, int STD) { - int result = (int) (random.nextGaussian() * STD + mean); - while (result > (mean + 3 * STD) || result < (mean - 3 * STD)) { - result = (int) random.nextGaussian() * STD + mean; + public int nextGaussianWithinRange(double rangeBegin, double rangeEnd) { + double rangeMean = (rangeEnd - rangeBegin) / 2.0; + double rangeSTD = (rangeEnd - rangeMean) / 3.0; + double result = random.nextGaussian() * rangeSTD + rangeMean; + while (result > rangeEnd || result < rangeBegin) { + result = random.nextGaussian() * rangeSTD + rangeMean; } - return result; + return (int) result; } public Point generatePeakForTransformationParabola(int pathDistance) { double maxTransformationScale = 0.2; - int peakX = nextGaussianWithinThreeSTDs(pathDistance / 2, pathDistance / 6); - int peakY = (int) (random.nextGaussian() * maxTransformationScale); + int peakX = nextGaussianWithinRange(0, pathDistance); + int peakY = nextGaussianWithinRange(0, pathDistance * maxTransformationScale); return new Point(peakX, peakY); } diff --git a/testfiles/cursorPathTest.txt b/testfiles/cursorPathTest.txt new file mode 100644 index 0000000..760be93 --- /dev/null +++ b/testfiles/cursorPathTest.txt @@ -0,0 +1,553 @@ +1527,568,2 +1527,568,10 +1527,568,15 +1527,568,21 +1527,568,28 +1527,568,34 +1527,568,41 +1527,568,47 +1527,568,54 +1527,568,60 +1527,568,67 +1527,568,74 +1527,568,81 +1527,568,89 +1527,568,95 +1527,568,101 +1527,568,106 +1527,568,112 +1527,568,118 +1527,568,125 +1527,568,131 +1527,568,138 +1527,568,145 +1527,568,152 +1527,568,158 +1527,568,164 +1527,568,170 +1527,568,177 +1527,568,184 +1527,568,189 +1527,568,194 +1527,568,200 +1527,568,206 +1527,568,213 +1527,568,220 +1527,568,227 +1527,568,232 +1527,568,238 +1527,568,245 +1527,568,251 +1527,568,257 +1527,568,264 +1527,568,271 +1527,568,278 +1527,568,285 +1527,568,292 +1527,568,299 +1527,568,304 +1527,568,310 +1527,568,316 +1527,568,321 +1527,568,328 +1527,568,334 +1527,568,342 +1527,568,350 +1527,568,357 +1527,568,364 +1527,568,371 +1527,568,376 +1527,568,381 +1527,568,387 +1527,568,393 +1527,568,398 +1527,568,404 +1527,568,409 +1527,568,416 +1527,568,422 +1527,568,429 +1527,568,435 +1527,568,441 +1527,568,447 +1527,568,452 +1527,568,458 +1527,568,463 +1527,568,469 +1527,568,476 +1527,568,483 +1527,568,490 +1527,568,497 +1527,568,504 +1527,568,512 +1527,568,518 +1527,568,524 +1527,568,531 +1527,568,538 +1527,568,545 +1527,568,552 +1527,568,558 +1527,568,565 +1527,568,572 +1527,568,579 +1527,568,585 +1527,568,592 +1527,568,600 +1527,568,606 +1527,568,614 +1527,568,621 +1527,568,627 +1527,568,633 +1527,568,639 +1527,568,646 +1527,568,651 +1527,568,656 +1527,568,662 +1527,568,669 +1527,568,676 +1527,568,683 +1527,568,689 +1527,568,695 +1527,568,701 +1527,568,707 +1527,568,713 +1527,568,719 +1527,568,724 +1527,568,730 +1527,568,736 +1527,568,742 +1527,568,748 +1527,568,754 +1527,568,760 +1527,568,768 +1527,568,774 +1527,568,781 +1527,568,788 +1527,568,794 +1527,568,800 +1527,568,806 +1527,568,813 +1527,568,820 +1527,568,828 +1527,568,834 +1527,568,840 +1527,568,848 +1527,568,855 +1527,568,861 +1527,568,868 +1527,568,874 +1527,568,882 +1527,568,888 +1527,568,894 +1527,568,899 +1527,568,906 +1527,568,912 +1527,568,920 +1527,568,927 +1527,568,933 +1527,568,939 +1527,568,945 +1527,568,952 +1527,568,960 +1527,568,966 +1527,568,973 +1527,568,980 +1527,568,986 +1527,568,994 +1527,568,1002 +1527,568,1008 +1527,568,1014 +1527,568,1020 +1527,568,1026 +1527,568,1032 +1527,568,1039 +1527,568,1045 +1527,568,1052 +1527,568,1059 +1527,568,1066 +1527,568,1073 +1527,568,1080 +1527,568,1086 +1527,568,1095 +1527,568,1102 +1527,568,1108 +1527,568,1114 +1527,568,1121 +1527,568,1128 +1353,641,1135 +1193,719,1157 +1193,719,1165 +1051,799,1173 +1051,799,1180 +931,872,1187 +830,928,1193 +830,928,1199 +735,976,1206 +735,976,1213 +650,1021,1218 +650,1021,1225 +590,1056,1231 +590,1056,1238 +566,1079,1244 +566,1079,1248 +559,1079,1253 +559,1079,1259 +558,1079,1264 +558,1079,1270 +558,1079,1277 +558,1079,1283 +559,1079,1289 +559,1079,1296 +605,1076,1302 +605,1076,1308 +706,1022,1315 +706,1022,1322 +848,934,1329 +848,934,1335 +982,850,1343 +1079,774,1349 +1079,774,1357 +1141,707,1364 +1172,653,1371 +1172,653,1379 +1187,613,1385 +1187,613,1392 +1190,577,1398 +1190,577,1404 +1190,563,1411 +1190,563,1417 +1190,563,1422 +1190,563,1428 +1190,563,1434 +1190,563,1440 +1190,563,1446 +1190,563,1451 +1190,563,1457 +1190,563,1462 +1190,563,1468 +1190,563,1474 +1190,563,1481 +1190,563,1488 +1190,563,1495 +1190,563,1502 +1190,563,1509 +1190,563,1516 +1190,563,1524 +1190,563,1530 +1190,563,1536 +1190,563,1543 +1190,563,1548 +1190,563,1554 +1190,563,1561 +1190,563,1568 +1190,563,1575 +1190,541,1581 +1190,526,1589 +1190,526,1595 +1186,497,1601 +1186,497,1607 +1140,449,1614 +1140,449,1622 +1083,407,1629 +1083,407,1635 +1005,386,1641 +936,377,1648 +936,377,1656 +866,377,1662 +866,377,1668 +805,377,1674 +805,377,1681 +746,383,1688 +746,383,1695 +701,397,1702 +701,397,1708 +681,406,1713 +681,406,1719 +672,415,1726 +671,421,1733 +671,421,1740 +671,428,1745 +671,428,1751 +671,437,1757 +671,437,1764 +676,445,1770 +676,445,1776 +689,455,1782 +689,455,1789 +713,473,1795 +713,473,1802 +743,495,1808 +743,495,1814 +772,514,1820 +772,514,1826 +808,523,1832 +808,523,1838 +844,528,1843 +844,528,1849 +886,528,1856 +886,528,1862 +953,512,1870 +1053,455,1877 +1053,455,1884 +1149,386,1891 +1149,386,1897 +1210,321,1903 +1210,321,1910 +1224,278,1916 +1224,278,1922 +1224,235,1928 +1224,235,1934 +1224,191,1941 +1224,148,1948 +1224,148,1955 +1188,104,1961 +1188,104,1966 +1188,104,1972 +1133,80,1978 +1133,80,1984 +1051,73,1990 +953,73,1997 +953,73,2005 +850,99,2010 +745,160,2021 +745,160,2028 +669,229,2032 +669,229,2040 +640,291,2046 +640,291,2052 +640,333,2059 +640,333,2065 +640,374,2071 +640,374,2078 +648,411,2085 +669,447,2093 +669,447,2098 +697,494,2104 +697,494,2114 +731,531,2119 +731,531,2125 +790,559,2131 +790,559,2138 +855,571,2146 +855,571,2152 +943,571,2158 +943,571,2162 +1049,555,2170 +1162,513,2178 +1162,513,2183 +1162,513,2191 +1248,472,2197 +1281,445,2202 +1281,445,2208 +1286,432,2214 +1286,432,2223 +1297,415,2229 +1305,401,2235 +1305,401,2244 +1317,382,2250 +1317,382,2259 +1328,364,2265 +1332,355,2271 +1332,355,2277 +1332,352,2283 +1332,352,2293 +1332,350,2297 +1332,350,2303 +1332,350,2309 +1332,350,2315 +1332,348,2321 +1332,348,2327 +1324,348,2333 +1324,348,2339 +1308,348,2345 +1308,348,2350 +1287,348,2357 +1287,348,2364 +1261,354,2372 +1261,354,2379 +1233,387,2386 +1204,430,2394 +1204,430,2399 +1185,481,2404 +1185,481,2411 +1179,536,2417 +1179,536,2423 +1179,579,2429 +1179,579,2435 +1179,621,2441 +1179,621,2448 +1179,659,2454 +1179,659,2461 +1199,682,2466 +1199,682,2472 +1233,696,2480 +1233,696,2486 +1266,705,2492 +1266,705,2498 +1300,709,2505 +1345,709,2511 +1345,709,2518 +1384,709,2525 +1384,709,2532 +1384,709,2538 +1384,709,2543 +1384,709,2550 +1384,709,2556 +1384,709,2563 +1384,709,2569 +1384,709,2576 +1384,709,2583 +1384,709,2589 +1384,709,2595 +1384,709,2600 +1384,709,2605 +1384,709,2611 +1384,709,2617 +1384,709,2624 +1384,709,2632 +1384,709,2640 +1384,709,2646 +1384,709,2651 +1384,709,2657 +1384,709,2662 +1384,709,2669 +1384,709,2675 +1384,709,2682 +1384,709,2689 +1384,709,2696 +1384,709,2702 +1384,709,2709 +1384,709,2717 +1384,709,2723 +1384,709,2729 +1384,709,2736 +1384,709,2744 +1384,709,2750 +1384,709,2757 +1384,709,2764 +1384,709,2772 +1380,709,2780 +1365,710,2787 +1365,710,2793 +1336,715,2801 +1336,715,2808 +1290,720,2814 +1290,720,2820 +1228,722,2827 +1228,722,2833 +1140,727,2838 +1140,727,2844 +1030,729,2850 +1030,729,2857 +904,729,2864 +804,729,2871 +804,729,2877 +742,729,2883 +742,729,2890 +693,723,2896 +693,723,2903 +629,707,2910 +629,707,2917 +561,694,2925 +499,678,2931 +499,678,2937 +499,678,2944 +458,661,2950 +428,644,2957 +428,644,2964 +400,621,2969 +400,621,2974 +378,597,2980 +378,597,2987 +365,578,2994 +365,578,3002 +358,564,3008 +358,564,3013 +356,559,3020 +356,556,3026 +356,556,3033 +356,556,3039 +356,556,3046 +356,556,3053 +356,556,3058 +356,556,3065 +356,556,3071 +356,556,3078 +356,556,3084 +356,556,3091 +356,556,3096 +356,556,3102 +356,556,3109 +356,556,3116 +356,556,3123 +356,556,3130 +356,556,3136 +356,556,3143 +356,556,3150 +356,556,3157 +356,556,3164 +356,556,3170 +356,556,3177 +356,556,3184 +356,556,3191 +356,547,3197 +356,547,3205 +353,536,3212 +353,536,3218 +344,500,3224 +344,500,3228 +320,439,3235 +320,439,3240 +299,376,3246 +299,376,3253 +274,324,3259 +274,324,3264 +251,284,3269 +251,284,3274 +231,254,3279 +231,254,3286 +214,234,3292 +214,234,3298 +204,226,3305 +204,226,3313 +200,223,3319 +200,223,3326 +199,223,3333 +199,223,3340 +199,223,3346 +199,223,3352 +199,223,3358 +199,223,3364 +199,223,3369 +199,223,3374 +199,223,3380 +199,223,3385 +202,224,3391 +202,224,3398 +212,230,3405 +235,242,3412 +235,242,3419 +268,256,3425 +268,256,3431 +331,271,3438 +331,271,3444 +439,293,3450 +439,293,3456 +590,326,3463 +750,359,3470 +750,359,3478 +905,391,3485 +905,391,3491 +1051,425,3499 +1051,425,3505 +1178,460,3510 +1178,460,3515 +1282,492,3522 +1282,492,3527 +1363,517,3533 +1363,517,3540 +1406,526,3546 +1406,526,3553 +1417,528,3560 +1420,528,3566 +1420,528,3572 +1420,528,3578