xxxxxxxxxx
// Inspired by 'Reach 2', at the URL https://p5js.org/examples/interaction-reach-2.html
let hair = [];
const hairCount = 500;
const segCount = 12;
const segLength = 40;
function setup() {
createCanvas(800, 800);
stroke(0, 0, 0, 40); // It's also fun to make the last parameter smaller or bigger
strokeWeight(1);
for (let angle = 0; angle < TWO_PI; angle += TWO_PI / hairCount) {
const x = width / 2 + cos(angle) * 400;
const y = height / 2 + sin(angle) * 400;
hair.push(new singleHair(x, y));
}
}
function draw() {
background(255);
hair.forEach((h) => {
h.calcAngles();
h.calcPositions();
h.show();
});
}
class Segment {
constructor() {
this.x = 0;
this.y = 0;
this.angle = 0;
}
}
class singleHair {
constructor(x, y) {
this.pos = Array(segCount)
.fill()
.map((a) => new Segment());
this.hairRoot = { x, y };
}
calcAngles() {
let parent = { x: mouseX, y: mouseY };
for (let child of this.pos) {
const dx = parent.x - child.x;
const dy = parent.y - child.y;
child.angle = atan2(dy, dx);
child.x = parent.x - cos(child.angle) * segLength;
child.y = parent.y - sin(child.angle) * segLength;
parent = child;
}
}
calcPositions() {
let parent = this.pos[this.pos.length - 1];
parent.x = this.hairRoot.x;
parent.y = this.hairRoot.y;
for (let j = this.pos.length - 1; j > 0; j--) {
let child = this.pos[j - 1];
child.x = parent.x + cos(parent.angle) * segLength;
child.y = parent.y + sin(parent.angle) * segLength;
parent = child;
}
}
show() {
for (const p of this.pos) {
line(
p.x,
p.y,
p.x + cos(p.angle) * segLength,
p.y + sin(p.angle) * segLength
);
}
}
}