Coffee Stain

Like the one on your desk

Log in to post a comment.

Canvas.setpenopacity(.1)

turtles = []

radius = 50
radiusRange = 15
resolution = 100
steps = 200
wigglyness = 0.75

for (j = 0; j < resolution; j++) {
    turtle = new Turtle()
    turtle.radians()
    turtle.penup()

    outwardness = staincurve(j / resolution)
    offset = radius + outwardness * radiusRange
    turtle.goto(offset, 0)

    turtle.pendown()
    turtles.push(turtle)
}

accum1 = 0
accum2 = 0
accum3 = 0

function walk(i) {
    progress = i / (steps - 1)
    originalAmount = progress < 0.5 ? progress * 2 : (1 - progress) * 2
    originalAmount = Math.pow(originalAmount, 0.75)

    accum1 += (Math.random() * 2 - 1) * wigglyness
    accum2 += (Math.random() * 2 - 1) * wigglyness
    accum3 += (Math.random() * 2 - 1) * wigglyness
    randWalk1 = Math.abs(accum1 + accum3)
    randWalk2 = Math.abs(accum2 + accum3)

    j = 0
    for (turtle of turtles) {
        outwardness = j / resolution

        randLow = -Math.min(randWalk1, randWalk2)
        randHigh = Math.max(randWalk1, randWalk2)
        radiusOffset = lerp(randLow, randHigh, outwardness)
        radiusOffset = radiusOffset * originalAmount

        outwardness = staincurve(outwardness)

        radiusWithOffset = radius + outwardness * radiusRange + radiusOffset
        x = Math.cos(Math.PI * 2 * progress) * radiusWithOffset
        y = Math.sin(Math.PI * 2 * progress) * radiusWithOffset
        
        turtle.goto(x, y)
        j++
    }

    console.log("i " + i + ": " + (i < steps))

    
    return i < steps - 1
}

function staincurve(x) {
    outside = 0.5 - Math.pow(1 - x, 2)
    inside = Math.pow(x, 2)
    return x < 0.5 ? inside : outside
}

function lerp(a, b, amount) {
    return (1 - amount) * a + amount * b
}