baby drawing

A random line, starting from the center, to imitate a baby drawing. Coded with Mistral (Pixtral-Large-2411)

Log in to post a comment.

// Create a new Turtle instance
const turtle = new Turtle();

// Adjustable variables
const lineLength = 580; // min=50, max=5000, step=10, Total length of the line
const segmentLength = 4; // min=1, max=10, step=1, Length of each segment in the randomized line
const maxTurnAngle = 62; // min=1, max=90, step=1, Maximum angle to turn at each step for smoothness
const boundary = 95; // min=50, max=100, step=5, Half side length for square drawing boundary
const boundaryBuffer = 25; // min=5, max=30, step=5, Boundary buffer to anticipate and avoid boundary

// Helper functions
function isWithinBounds(x, y) {
    return Math.abs(x) <= boundary && Math.abs(y) <= boundary;
}

function distanceToClosestBoundary(x, y) {
    const distToLeft = boundary - Math.abs(x);
    const distToRight = boundary - Math.abs(x);
    const distToTop = boundary - Math.abs(y);
    const distToBottom = boundary - Math.abs(y);

    return Math.min(distToLeft, distToRight, distToTop, distToBottom);
}

// Set initial conditions
turtle.penup();
turtle.goto(0, 0);
turtle.pendown();

let totalPathLength = 0;

function walk(i) {
    if (totalPathLength >= lineLength) {
        return false;
    }

    // Get current position and heading
    let currentX = turtle.x();
    let currentY = turtle.y();
    let currentHeading = turtle.heading();

    // Calculate new heading with a small random change
    let newHeading;
    let avoidanceFactor = 0;

    if (distanceToClosestBoundary(currentX, currentY) < boundaryBuffer) {
        // Adjust heading to avoid boundary
        let directionToCenter = (Math.atan2(-currentY, -currentX) * 180 / Math.PI + 360) % 360;
        let angleDiff = directionToCenter - currentHeading;
        avoidanceFactor = Math.max(1, boundaryBuffer / distanceToClosestBoundary(currentX, currentY));
        newHeading = currentHeading + angleDiff / avoidanceFactor;
    } else {
        newHeading = currentHeading + (Math.random() - 0.5) * 2 * maxTurnAngle;
    }

    // Move to the new position
    let newX = currentX + segmentLength * Math.cos(newHeading * Math.PI / 180);
    let newY = currentY + segmentLength * Math.sin(newHeading * Math.PI / 180);

    if (isWithinBounds(newX, newY)) {
        turtle.setheading(newHeading);
        turtle.goto(newX, newY);
        totalPathLength += segmentLength;
    } else {
        // Redirect if the move is beyond boundary
        turtle.right(180 + (Math.random() - 0.5) * maxTurnAngle);
    }

    return true;
}

// Set canvas pen opacity if desired
Canvas.setpenopacity(1);