xxxxxxxxxx
152
let cam;
let axis;
let arrowArray = [];
// let heartPoints = []; // Array to store points on the heart
// let maxDistance = 300; // Maximum distance for point generation
// let sigma = 15; // Standard deviation for the Gaussian function
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
axis = createGraphics(windowWidth, windowHeight, WEBGL);
drawAxis();
arrowArray.push(new Arrow(0, 0, 1000));
/* Generate points on the heart to use as a reference
for (let t = 0; t < TWO_PI; t += 0.01) {
let x = functionHeartX(t);
let y = functionHeartY(t);
heartPoints.push(createVector(x + axis.width / 2, -y + axis.height / 2)); // Center the heart
}*/
}
function draw() {
background(10);
lights();
ambientLight(50);
pointLight(
255, 0, 0, // color
0, 0, 0 // position
);
// frameRate(60);
orbitControl();
// use Graphics.axis as the texture of a plane
// create 2D objects in 3D space
texture(axis);
plane(windowWidth / 1.2, windowHeight / 1.2);
// display all arrows in arrowArray for 1 frame
if (arrowArray[0]) {
for (let i = 1; j = arrowArray[i] ;i += 1) {
if (j._3Dz < -50) {
arrowArray.splice(i, 1);
} else {
j.arrowDisplay();
}
}
}
// add new arrows to arrowArray
if (mouseIsPressed) {
let t = random(TWO_PI)
let x = functionHeartX(t);
let y = functionHeartY(t);
arrowArray.push(new Arrow(x, -y, 1000));
/* Check distance to the heart
let closestDistance = Infinity;
for (let heartPoint of heartPoints) {
let d = dist(x + axis.width / 2, -y + axis.height / 2, heartPoint.x, heartPoint.y);
if (d < closestDistance) {
closestDistance = d;
}
}
// Calculate probability using Gaussian decay
let probability = gaussianProbability(closestDistance);
// Add point based on probability
if (random() < probability) {
arrowArray.push(new Arrow(x, -y, 1000));
}*/
}
}
function drawAxis() {
// translate to 2D coordinate system
axis.translate(-axis.width / 2, -axis.height / 2);
axis.background(10);
// draw the axises
axis.stroke('white');
axis.line(0, axis.height / 2, axis.width, axis.height / 2);
axis.line(axis.width / 2, 0, axis.width / 2, axis.height);
// draw the marks on the y axis
for (let i = 0; i < width; i += axis.height / 20) {
axis.line(axis.width / 2,
0 + i,
axis.width / 2 + 5,
0 + i);
}
// draw the marks on the x axis
for (let i = 0; i < width; i += axis.width / 20) {
axis.line(0 + i,
axis.height / 2,
0 + i,
axis.height / 2 - 5);
}
}
class Arrow {
constructor (x, y, z) {
this._3Dx = x;
this._3Dy = y;
this._3Dz = z;
}
// display the arrow for 1 frame
arrowDisplay() {
if (this._3Dz > 0) { // if the arrow hasn't reach the axis
this._3Dz -= 10; // the speed in which the arrows move
} else if (this._3Dz <= 0) {
this._3Dz -= 0.01;
}
push();
translate(this._3Dx, this._3Dy, this._3Dz);
rotateX(PI / 2); // rotate to make the top/bottom facing the axis
fill('white');
noStroke();
cylinder(2, 100);
pop();
}
}
function functionSine(x) {
return 50 * sin(x * 0.05);
}
// Heart shape function
function functionHeartX(t) {
return 160 * pow(sin(t), 3);
}
function functionHeartY(t) {
return 150 * cos(t) - 55 * cos(2 * t) - 30 * cos(3 * t) - 10 * cos(4 * t);
}
/* Gaussian probability function
function gaussianProbability(distance) {
if (distance > maxDistance) {
return 0; // No points beyond maxDistance
}
return exp(-pow(distance, 2) / (2 * pow(sigma, 2))); // Gaussian decay
} */