Avoid neighbours

A Perlin noise flow field with added behaviour to avoid neighbours.

import coracle.*
import kotlin.math.cos
import kotlin.math.sin

class PerlinNoiseDrawing2: Drawing() {

    val agents = mutableListOf()
    val agentCount = 450
    var scale = 0.01f
    var speed = 1.2f
    var elapsed = 0

    var frame = 0

    override fun setup() {
        size(450, 450)

        repeat(agentCount){
            agents.add(Agent(random(width), random(height)))
        }
    }

    override fun draw() {
        stroke(0xffffff, 0.75f)
        frame++
        agents.forEach { agent ->
            agent
                .avoidNearest()
                .updateFlowField()
                .checkBounds()
                .draw()
        }

        elapsed++
        if(elapsed > 350){
            Perlin.newSeed()
            scale = random(0.001f, 0.02f)
            speed = random(0.8f, 2f)
            elapsed = 0
        }

        foreground(0x000000, 0.035f)
    }

    inner class Agent(x: Float, y: Float): Vector(x, y) {

        var age = 0
        var deathAge = random(100, 340)

        fun updateFlowField(): Agent{
            if(frame % 3 != 0) return this
            age++
            val a = TAU * Perlin.noise(x * scale, y * scale)
            var direction = direction(Vector( x + (cos(a)).toFloat(), y + (sin(a) ).toFloat()))
            direction.normalize()
            direction *= 0.8f
            this.x += direction.x * speed
            this.y += direction.y * speed

            return this
        }

        fun avoidNearest(): Agent{
            var closestDistance = Float.MAX_VALUE
            var closestIndex = -1

            agents.forEachIndexed { index, other ->
                if(other != this){
                    val distance = distance(other)
                    if(distance < closestDistance){
                        closestIndex = index
                        closestDistance = distance
                    }
                }
            }

            val closest = agents[closestIndex]
            if(distance(closest) < 35) {
                var direction = direction(closest)
                direction.normalize()
                direction *= -0.3f

                this.x += direction.x
                this.y += direction.y
            }
            return this
        }

        fun checkBounds(): Agent{
            if(age >= deathAge || x < 0 || x > width || y < 0 || y > height ){
                x = random(width)
                y = random(height)
                age = 0
                deathAge = random(100, 340)
            }
            return this
        }

        fun draw() = point(x, y)
    }
}