Autonomous Agents
For this week’s assignment in The Nature of Code I learned about coding movement for autonomous agents with the key movement characteristics breaking down into seeking objects and avoiding objects. The goal of this assignment is being able to program behaviors for how individual objects respond to their environment and allowing that to happen in a dynamic way.
My initial concept for this assignment was to recreate movement similar to the growth of a plant where only the new growth is capable of movement.
I started my coding with creating a Vine object that is created on mousePressed() and pushed to a plants array. On each loop through draw the vine object slowly grows in pursuit of the moving sun, and at set growth points pushes its coordinates to an array creating a new node for further growth to start from.
With more time for this project I could imagine using the node array in each vine object as a starting point for further growth of leaves or other branches of the vine.
In the process of working on this sketch I found myself drawn to a number of aesthetic choices that minimized the look. The end result is much more abstract than the plants that inspired the work, but I find something about the slow motion chase intriguing.
// Brandon Roots // ITP 2021 // The Nature of Code let plant = []; let sun; function setup() { createCanvas(windowWidth, windowHeight); background(220); sun = createVector(0, 0); } function draw() { background(220, 100); for (let [i, vine] of plant.entries()) { vine.grow(); vine.update(sun.x, sun.y); vine.show(); } noStroke(); fill(255, 50, 0); sun.x = cos((millis()/20000)%(TWO_PI))*200; sun.y = sin((millis()/20000)%(TWO_PI))*200; sun.x += windowWidth/2; sun.y += windowHeight/2; circle(sun.x, sun.y, 100); } function mousePressed() { // On mouse press push new vine to plant array let newPlant = new Vine(mouseX, mouseY); plant.push(newPlant); } class Vine { constructor(x, y, offset = 0){ this.vine = []; this.newSegment = createVector(x, y); this.vine.push(this.newSegment); this.newLength = 0; this.growRate = 0.1; this.segmentMax = 30; this.wave = 0; this.amplitude = 1; this.maxForce = 10; this.offset = offset; this.radius = random (5,15); } // grow new segment to the vine array until it reaches a maximum length, then start new segment grow(){ this.newLength += this.growRate; if(this.newLength > this.segmentMax){ //push new end point to this.vine array this.vine.push(this.newSegment); this.newLength = 0.01; } // trim trail length if(this.vine.length > 50){ this.vine.splice(0,1); } } update(x, y){ let currentEndPoint = this.vine[this.vine.length - 1]; let goal = createVector(x, y); let newVector = p5.Vector.sub(goal, currentEndPoint); let newHeading = newVector.heading(); // Something here to limit the change in this.newSegment //this.newSegment.setHeading(newHeading); this.newSegment = newVector; this.newSegment.rotate(this.wave); this.newSegment.setMag(this.newLength); this.newSegment.x += currentEndPoint.x; this.newSegment.y += currentEndPoint.y - this.offset; this.wave = sin((millis()/100)%(PI))/(this.newLength/3); } show(){ noFill(); stroke(250); beginShape(); for(let i = 0; i < this.vine.length; i++){ vertex(this.vine[i].x, this.vine[i].y); } vertex(this.newSegment.x, this.newSegment.y); endShape(); noStroke(); fill(150); circle(this.newSegment.x, this.newSegment.y, this.radius); } }