xxxxxxxxxx
163
let sensorValues = []; // Array to store sensor readings
let ripples = [];
let lotuses = [];
let caustics = [];
let serial; // WebSerial object
let port; // Port object
let reader; // Reader for serial data
let decoder = new TextDecoder(); // Decoder for incoming serial data
function setup() {
createCanvas(1920, 1080); // canvas size
noSmooth();
// Initialize caustics grid
for (let i = 0; i < width; i += 40) {
for (let j = 0; j < height; j += 40) {
caustics.push({ x: i, y: j, offset: random(TWO_PI) });
}
}
// Create a button to connect to the serial port
let connectButton = createButton("Connect to Serial");
connectButton.position(10, 10);
connectButton.mousePressed(connectToSerial);
}
function draw() {
background(0, 0, 150); // Deep blue water
// Draw caustics
drawCaustics();
// Draw ripples
for (let i = ripples.length - 1; i >= 0; i--) {
let ripple = ripples[i];
drawRipple(ripple.x, ripple.y, ripple.size);
ripple.size += 2; // Ripple growth
if (ripple.size > 200) {
// Ripple threshold
// When the ripple grows large, create a flower at its location
lotuses.push({
x: ripple.x,
y: ripple.y,
size: ripple.pressure,
frame: 0,
});
ripples.splice(i, 1); // Remove ripple after creating a flower
}
}
// Draw and animate blooming flowers
for (let i = lotuses.length - 1; i >= 0; i--) {
let lotus = lotuses[i];
drawBloomingLotus(lotus.x, lotus.y, lotus.size, lotus.frame);
if (lotus.frame < 30) {
lotus.frame++; // Continue blooming animation
} else if (lotus.frame >= 30) {
// Remove the flower after the animation completes
lotuses.splice(i, 1);
}
}
// Use sensor values to create ripples
if (sensorValues.length > 0) {
for (let r = 0; r < sensorValues.length; r++) {
for (let c = 0; c < sensorValues[r].length; c++) {
if (sensorValues[r][c] > 100) {
// Trigger ripples for high-pressure values
let x = map(c, 0, sensorValues[r].length, width / 6, (5 * width) / 6);
let y = map(r, 0, sensorValues.length, height / 5, (4 * height) / 5);
let pressure = sensorValues[r][c]; // Get pressure value
ripples.push({
x,
y,
size: 20,
pressure: map(pressure, 100, 1023, 100, 300),
});
}
}
}
}
}
async function connectToSerial() {
// Request a port and open a connection
try {
port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
serial = port.readable.getReader();
// Start reading data from the serial port
readSerial();
} catch (err) {
console.error("Error connecting to serial:", err);
}
}
async function readSerial() {
while (port.readable) {
try {
const { value, done } = await serial.read();
if (done) {
serial.releaseLock();
break;
}
// Decode the data and process it
const data = decoder.decode(value);
processSerialData(data.trim());
} catch (err) {
console.error("Error reading serial data:", err);
break;
}
}
}
function processSerialData(data) {
// Parse CSV data from Arduino
let rows = data.split("\n");
sensorValues = rows.map((row) =>
row.split(",").map((val) => parseInt(val.trim()))
);
}
function drawRipple(x, y, size) {
noFill();
stroke(255, 255, 255, 30);
strokeWeight(3); // Adjusted stroke weight for larger canvas
ellipse(x, y, size, size);
}
function drawBloomingLotus(x, y, size, frame) {
push();
translate(x, y);
let scaleAmount = map(frame, 0, 100, 0, 1); // Animation scaling
noStroke();
// Draw petals
fill(255, 182, 193);
for (let angle = 0; angle < TWO_PI; angle += PI / 6) {
let petalX = cos(angle) * size * scaleAmount;
let petalY = sin(angle) * size * scaleAmount;
ellipse(petalX, petalY, size * 0.6 * scaleAmount); // Adjusted petal size
}
// Draw the center of the flower
fill(255, 105, 180);
ellipse(0, 0, size * 0.5 * scaleAmount); // Adjusted center size
pop();
}
function drawCaustics() {
noStroke();
fill(0, 150, 250, 20);
for (let caustic of caustics) {
let wave = sin(frameCount * 0.03 + caustic.offset) * 20; // Adjusted wave size
ellipse(caustic.x + wave, caustic.y + wave, 70, 70); // Adjusted caustic size
}
}