Agentic Drawing with Processing

[java] int numDots = 500; // Number of dots aDOT[] dots = new aDOT[numDots]; // Array to hold the dots …

[java]

int numDots = 500; // Number of dots
aDOT[] dots = new aDOT[numDots]; // Array to hold the dots
PImage img; // Image to influence particle motion
float noiseScale = 0.01; // Scale of the Perlin noise

void setup() {
size(800, 800);
img = loadImage("face.png"); // Load the image
img.resize(width, height); // Resize the image to match the canvas size
for (int i = 0; i < numDots; i++) {
dots[i] = new aDOT(random(width), random(height));
}
background(255);
noStroke();
}

void draw() {
//
/*
fill(255, 6);
rect(0, 0, width, height);
*/
for (int i = 0; i < numDots; i++) {
dots[i].update();
dots[i].display();
}
}

class aDOT {
PVector position;
PVector velocity;
float maxSpeed = 1;

aDOT(float x, float y) {
position = new PVector(x, y);
velocity = PVector.random2D();
}

void update() {
int imgX = int(position.x);
int imgY = int(position.y);
if (imgX >= 0 && imgX < img.width && imgY >= 0 && imgY < img.height) {
float brightnessValue = brightness(img.get(imgX, imgY));
float angle = map(brightnessValue, 0, 255, 0, TWO_PI);
PVector direction = new PVector(cos(angle), sin(angle));
direction.mult(0.05); // Scale the influence of the brightness (even lower influence)
velocity.add(direction);
}
PVector randomWander = PVector.random2D().mult(0.5); // Small random component
velocity.add(randomWander);
velocity.limit(maxSpeed);
position.add(velocity);
edges();
}

void display() {
int imgX = int(position.x);
int imgY = int(position.y);
float brightnessValue = brightness(img.get(imgX, imgY));
float dotSize = map(brightnessValue, 0, 255, 4, 1); // Map brightness to dot size (darker = bigger)

fill(0,44);
ellipse(position.x, position.y, dotSize, dotSize);
}

void edges() {
if (position.x > width) position.x = 0;
if (position.x < 0) position.x = width;
if (position.y > height) position.y = 0;
if (position.y < 0) position.y = height;
}
}

[/java]

dot drawing + mouse interaction

[java]

int numDots = 800; // Number of dots
aDOT[] dots = new aDOT[numDots]; // Array to hold the dots
PImage img; // Image to influence particle motion
float noiseScale = 0.004; // Scale of the Perlin noise
int respawnTimeMin = 5000; // Minimum respawn time in milliseconds (5 seconds)
int respawnTimeMax = 10000; // Maximum respawn time in milliseconds (10 seconds)
int lastRespawnTime = 0; // Time of the last respawn

void setup() {
size(800, 800);
img = loadImage("face2.png"); // Load the image
img.resize(width, height); // Resize the image to match the canvas size
for (int i = 0; i < numDots; i++) {
respawnDot(i);
}
background(255);
noStroke();
}

void draw() {
for (int i = 0; i < numDots; i++) {
dots[i].update();
dots[i].display();
respawnIfNeeded(i);
}
}

void respawnIfNeeded(int index) {
int currentTime = millis();
if (currentTime – lastRespawnTime > dots[index].respawnTime) {
respawnDot(index);
}
}

void respawnDot(int index) {
dots[index] = new aDOT(random(width), random(height));
dots[index].respawnTime = int(random(respawnTimeMin, respawnTimeMax));
lastRespawnTime = millis();
}

class aDOT {
PVector position;
PVector velocity;
float maxSpeed = 2.5;
int respawnTime; // Respawn time for the dot
float brightnessOffset; // Brightness offset for the dot's color

aDOT(float x, float y) {
position = new PVector(x, y);
velocity = PVector.random2D();
brightnessOffset = random(-100, 100); // Random brightness offset
}

void update() {
if (mousePressed) { // Check if mouse is pressed
PVector mousePos = new PVector(mouseX, mouseY);
PVector directionToMouse = PVector.sub(mousePos, position).normalize().mult(0.2); // Calculate direction towards mouse
velocity.add(directionToMouse); // Add direction towards mouse to velocity
}

int imgX = int(position.x);
int imgY = int(position.y);
if (imgX >= 0 && imgX < img.width && imgY >= 0 && imgY < img.height) {
float brightnessValue = brightness(img.get(imgX, imgY)) + brightnessOffset; // Apply brightness offset
if (brightnessValue > 160) {
fill(255); // Change color to white
} else {
fill(0, 44); // Default color
}
float angle = map(brightnessValue, 0, 255, 0, TWO_PI);
PVector direction = new PVector(cos(angle), sin(angle));
direction.mult(0.12); // Scale the influence of the brightness (even lower influence)
velocity.add(direction);
}
PVector randomWander = PVector.random2D().mult(0.45); // Small random component
velocity.add(randomWander);
velocity.limit(maxSpeed);
position.add(velocity);
edges();
}

void display() {
int imgX = int(position.x);
int imgY = int(position.y);
float brightnessValue = brightness(img.get(imgX, imgY)) + brightnessOffset; // Apply brightness offset
float dotSize = map(brightnessValue, 0, 255, 3, 1); // Map brightness to dot size (darker = bigger)
circle(position.x, position.y, dotSize);
}

void edges() {
if (position.x > width) position.x = 0;
if (position.x < 0) position.x = width;
if (position.y > height) position.y = 0;
if (position.y < 0) position.y = height;
}
}

[/java]

Automatic Drawing + Mouse Interaction + Live Video Capture

[java]

import processing.video.*;

int numDots = 800; // Number of dots
aDOT[] dots = new aDOT[numDots]; // Array to hold the dots
PImage img; // Image to influence particle motion
Capture cam; // Webcam capture
float noiseScale = 0.004; // Scale of the Perlin noise
int respawnTimeMin = 5000; // Minimum respawn time in milliseconds (5 seconds)
int respawnTimeMax = 10000; // Maximum respawn time in milliseconds (10 seconds)
int lastRespawnTime = 0; // Time of the last respawn
int lastCamUpdate = 0; // Time of the last webcam update
int camUpdateInterval = 3000; // Webcam update interval in milliseconds (3 seconds)

void setup() {
size(800, 800);
cam = new Capture(this, width, height);
cam.start();
for (int i = 0; i < numDots; i++) {
respawnDot(i);
}
background(255);
noStroke();
}

void draw() {
if (cam.available() && millis() – lastCamUpdate > camUpdateInterval) {
cam.read();
img = cam.get(); // Get the current frame from webcam
img.resize(width, height); // Resize the image to match the canvas size
lastCamUpdate = millis();
}

for (int i = 0; i < numDots; i++) {
dots[i].update();
dots[i].display();
respawnIfNeeded(i);
}

//set( 0,0,cam );
}

void respawnIfNeeded(int index) {
int currentTime = millis();
if (currentTime – lastRespawnTime > dots[index].respawnTime) {
respawnDot(index);
}
}

void respawnDot(int index) {
dots[index] = new aDOT(random(width), random(height));
dots[index].respawnTime = int(random(respawnTimeMin, respawnTimeMax));
lastRespawnTime = millis();
}

class aDOT {
PVector position;
PVector velocity;
float maxSpeed = 2.5;
int respawnTime; // Respawn time for the dot
float brightnessOffset; // Brightness offset for the dot's color

aDOT(float x, float y) {
position = new PVector(x, y);
velocity = PVector.random2D();
brightnessOffset = random(-100, 100); // Random brightness offset
}

void update() {
if (mousePressed) { // Check if mouse is pressed
PVector mousePos = new PVector(mouseX, mouseY);
PVector directionToMouse = PVector.sub(mousePos, position).normalize().mult(0.2); // Calculate direction towards mouse
velocity.add(directionToMouse); // Add direction towards mouse to velocity
}

int imgX = int(position.x);
int imgY = int(position.y);
if (img != null && imgX >= 0 && imgX < img.width && imgY >= 0 && imgY < img.height) {
float brightnessValue = brightness(img.get(imgX, imgY)) + brightnessOffset; // Apply brightness offset
if (brightnessValue > 160) {
fill(255); // Change color to white
} else {
fill(0, 44); // Default color
}
float angle = map(brightnessValue, 0, 255, 0, TWO_PI);
PVector direction = new PVector(cos(angle), sin(angle));
direction.mult(0.12); // Scale the influence of the brightness (even lower influence)
velocity.add(direction);
}
PVector randomWander = PVector.random2D().mult(0.45); // Small random component
velocity.add(randomWander);
velocity.limit(maxSpeed);
position.add(velocity);
edges();
}

void display() {
if (img != null) {
int imgX = int(position.x);
int imgY = int(position.y);
float brightnessValue = brightness(img.get(imgX, imgY)) + brightnessOffset; // Apply brightness offset
float dotSize = map(brightnessValue, 0, 255, 3, 1); // Map brightness to dot size (darker = bigger)
circle(position.x, position.y, dotSize);
}
}

void edges() {
if (position.x > width) position.x = 0;
if (position.x < 0) position.x = width;
if (position.y > height) position.y = 0;
if (position.y < 0) position.y = height;
}
}

void captureEvent(Capture c) {
c.read();
}

[/java]

web-based P5.JS based port

This is 1:1 ported version of the webcam based approach running on a website.

[js collape=“true“]

let numDots = 500; // Number of dots
let dots = []; // Array to hold the dots
let img; // Image to influence particle motion
let cam; // Webcam capture
let noiseScale = 0.004; // Scale of the Perlin noise
let respawnTimeMin = 5000; // Minimum respawn time in milliseconds (5 seconds)
let respawnTimeMax = 10000; // Maximum respawn time in milliseconds (10 seconds)
let lastRespawnTime = 0; // Time of the last respawn
let lastCamUpdate = 0; // Time of the last webcam update
let camUpdateInterval = 3000; // Webcam update interval in milliseconds (3 seconds)

function setup() {
createCanvas(800, 800);

// Create webcam capture
cam = createCapture(VIDEO);
cam.size(width, height);
cam.hide(); // Hide the default video element

// Initialize dots
for (let i = 0; i < numDots; i++) {
respawnDot(i);
}

background(255);
noStroke();
}

function draw() {
// Update webcam image at intervals
if (millis() – lastCamUpdate > camUpdateInterval) {
img = cam.get(); // Get the current frame from webcam
lastCamUpdate = millis();
}

// Update and display dots
for (let i = 0; i < numDots; i++) {
dots[i].update();
dots[i].display();
respawnIfNeeded(i);
}
}

function respawnIfNeeded(index) {
let currentTime = millis();
if (currentTime – lastRespawnTime > dots[index].respawnTime) {
respawnDot(index);
}
}

function respawnDot(index) {
dots[index] = new aDOT(random(width), random(height));
dots[index].respawnTime = int(random(respawnTimeMin, respawnTimeMax));
lastRespawnTime = millis();
}

class aDOT {
constructor(x, y) {
this.position = createVector(x, y);
this.velocity = p5.Vector.random2D();
this.maxSpeed = 2.5;
this.respawnTime = 0; // Will be set in respawnDot
this.brightnessOffset = random(-100, 100); // Random brightness offset
}

update() {
if (mouseIsPressed) { // Check if mouse is pressed
let mousePos = createVector(mouseX, mouseY);
let directionToMouse = p5.Vector.sub(mousePos, this.position).normalize().mult(0.2);
this.velocity.add(directionToMouse);
}

if (img && img.width > 0) {
let imgX = int(this.position.x);
let imgY = int(this.position.y);

// Ensure coordinates are within image bounds
imgX = constrain(imgX, 0, img.width – 1);
imgY = constrain(imgY, 0, img.height – 1);

let pixelColor = img.get(imgX, imgY);
let brightnessValue = brightness(pixelColor) + this.brightnessOffset;

let angle = map(brightnessValue, 0, 255, 0, TWO_PI);
let direction = createVector(cos(angle), sin(angle));
direction.mult(0.12); // Scale the influence of the brightness
this.velocity.add(direction);
}

let randomWander = p5.Vector.random2D().mult(0.45); // Small random component
this.velocity.add(randomWander);
this.velocity.limit(this.maxSpeed);
this.position.add(this.velocity);
this.edges();
}

display() {
if (img && img.width > 0) {
let imgX = int(this.position.x);
let imgY = int(this.position.y);

// Ensure coordinates are within image bounds
imgX = constrain(imgX, 0, img.width – 1);
imgY = constrain(imgY, 0, img.height – 1);

let pixelColor = img.get(imgX, imgY);
let brightnessValue = brightness(pixelColor) + this.brightnessOffset;

let dotSize = map(brightnessValue, 0, 255, 3, 1); // Map brightness to dot size

if (brightnessValue > 160) {
fill(255,180); // Change color to white
dotSize = map(brightnessValue, 0, 255, 1, 3);
} else {
fill(0, 34); // Default color
}

circle(this.position.x, this.position.y, dotSize);
}
}

edges() {
if (this.position.x > width) this.position.x = 0;
if (this.position.x < 0) this.position.x = width;
if (this.position.y > height) this.position.y = 0;
if (this.position.y < 0) this.position.y = height;
}
}

[/js]

FULL CODE ONLINE EDITOR