Generative Agency

An interactive generative program that consists of a text and numerous agents. These agents are either placed inside the text or surround the text and move around the canvas based on the two-dimensional noise values applied to them. The user can control a number of parameters to change the appearance of the sketch according to their preferences.

Agents

An agent has the following properties: coordinates, a vector generated by the setCoordinates() class method which positions the agent on the canvas. As shown in the code fragment below, this method runs while the coordinates vector is null or depending on the withinText value, while the agent is placed inside or outside the text.

setCoordinates() {
    while (this.coordinates == null || 
            props.withinText && !this.isWithinText(this.coordinates) || 
            !props.withinText && this.isWithinText(this.coordinates)) {
        this.coordinates = createVector(random(width), random(height)); 
    } 
}

The health property is a randomnly generated value between 0.1 and maxHealth or the maximum health of an agent. This is initally set to 0.3. The lifeSpan property is used to decrease the agent's health. The movement of the agent stops once it has no health left. These properties affect the look of the sketch. The color of the agent is randomly selected from from a colour palette that the program can also generate for the user. Each agent moves around the canvas based on its angle. The code fragment below shows the code within the update() class method.

update() {
    let scaleX = this.coordinates.x * noiseScale;
    let scaleY = this.coordinates.y * noiseScale;
    let noiseVal = noise(scaleX, scaleY);
    this.angle = map(noiseVal, 0, 1, 0, TWO_PI) * noiseStrength;
    this.coordinates.x += cos(this.angle) * stepSize;
    this.coordinates.y += sin(this.angle) * stepSize;
    this.health -= this.lifeSpan;
}

The update() method moves the agent around the canvas and decreases its health. As shown above, the x and y coordinates of the agent are scaled by the noiseScale value before it passed to p5's noise() method. Similar to the health and lifeSpan properties, this value affects how the agents are drawn on the canvas. noiseScale is then mapped to an angle between 0 and TWO_PI. The angle is scaled by the noiseStrength value which affects the direction of the agent. stepSize affects the speed of the agent's movement as well as the appearance of the sketch. The agents are displayed on the canvas as points, ellipses, or lines.

The Text

The text is rendered into an off-screen graphics buffer so that the current pixels of an agent can be retrieved using p5's get() method and compared with the colour of the text, which is set to black. These tasks are performed by the Article class method isWithinText(). This method accepts a vector as a parameter, returns a boolean value, and is used to set the coordinates of the agent on the canvas.

isWithinText(_coordinates) {
    let px = graphics.get(floor(_coordinates.x), floor(_coordinates.y));
    return (
        px[0] == graphicsColor.levels[0] &&
        px[1] == graphicsColor.levels[1] &&
        px[2] == graphicsColor.levels[2] &&
        px[3] == graphicsColor.levels[3]
    );
}

Results

The following images show some outputs generated by the program.

Result 1
Result 2
Result 3
Result 4