private ArrayList<RSTile> generatePath(Line[] lines) { double minStep = 5, maxStep = 10, wander = 3; if (lines.length < 2) return null; ArrayList<RSTile> path = new ArrayList<RSTile>(); Line l1, l2 = lines[0]; double distFromCenter = random(0, l2.getDistance() + 1); RSTile p = l2.translate((int) distFromCenter); distFromCenter = l2.getDistance() / 2 - distFromCenter; double centerXdist, centerYdist, line1Xdist, line1Ydist, line2Xdist, line2Ydist; double line1dist, line2dist, centerDist; double x, y; double distOnLine, last, cap1, cap2, move; double distFromCenterX1, distFromCenterY1, distFromCenterX2, distFromCenterY2; double force1, force2, slopeX, slopeY, slopeDist; boolean finished; int lastX = p.getX(), lastY = p.getY(), curX, curY; double dist, xdist, ydist; for (int i = 1; i < lines.length; i++) { l1 = l2; l2 = lines[i]; centerXdist = l2.getCenterX() - l1.getCenterX(); centerYdist = l2.getCenterY() - l1.getCenterY(); centerDist = Math.sqrt(centerXdist * centerXdist + centerYdist * centerYdist); line1Xdist = l2.getX() - l1.getX(); line1Ydist = l2.getY() - l1.getY(); line2Xdist = l2.getX2() - l1.getX2(); line2Ydist = l2.getY2() - l1.getY2(); centerXdist /= centerDist; centerYdist /= centerDist; line1Xdist /= centerDist; line1Ydist /= centerDist; line2Xdist /= centerDist; line2Ydist /= centerDist; distOnLine = 0; last = 0; finished = false; while (!finished) { distOnLine += random(minStep, maxStep); if (distOnLine >= centerDist) { distOnLine = centerDist; finished = true; } x = centerXdist * distOnLine + l1.getCenterX(); y = centerYdist * distOnLine + l1.getCenterY(); distFromCenterX1 = x - (line1Xdist * distOnLine + l1.getX()); distFromCenterY1 = y - (line1Ydist * distOnLine + l1.getY()); distFromCenterX2 = x - (line2Xdist * distOnLine + l1.getX2()); distFromCenterY2 = y - (line2Ydist * distOnLine + l1.getY2()); slopeX = distFromCenterX2 - distFromCenterX1; slopeY = distFromCenterY2 - distFromCenterY1; slopeDist = Math.sqrt(slopeX * slopeX + slopeY * slopeY); slopeX /= slopeDist; slopeY /= slopeDist; line1dist = Math.sqrt(distFromCenterX1 * distFromCenterX1 + distFromCenterY1 * distFromCenterY1); line2dist = Math.sqrt(distFromCenterX2 * distFromCenterX2 + distFromCenterY2 * distFromCenterY2); move = (distOnLine - last) / maxStep * wander; force1 = line1dist + distFromCenter; force2 = line2dist - distFromCenter; cap1 = Math.min(move, force1); cap2 = Math.min(move, force2); if (force1 < 0) distFromCenter -= force1; else if (force2 < 0) distFromCenter += force2; else distFromCenter += random(-cap1, cap2); if (finished) { RSTile t = l2.translateFromCenter(distFromCenter); curX = t.getX(); curY = t.getY(); } else { curX = (int) Math.round(distOnLine * centerXdist + l1.getCenterX() + distFromCenter * slopeX); curY = (int) Math.round(distOnLine * centerYdist + l1.getCenterY() + distFromCenter * slopeY); } xdist = curX - lastX; ydist = curY - lastY; dist = Math.sqrt(xdist * xdist + ydist * ydist); xdist /= dist; ydist /= dist; for (int j = 0; j < dist; j++) path.add( new RSTile((int) Math.round(xdist * j + lastX), (int) Math.round(ydist * j + lastY))); last = distOnLine; lastX = curX; lastY = curY; } } return cutUp(path); }