104 lines
2.3 KiB
JavaScript
104 lines
2.3 KiB
JavaScript
var vec = p5.Vector;
|
|
|
|
class Segment {
|
|
constructor(x, y, size) {
|
|
this.size = size;
|
|
this.pos = new vec(x, y);
|
|
this.forward = new vec(0, 0);
|
|
}
|
|
|
|
get_rel(angleOffset, dist) {
|
|
let dir = vec.rotate(this.forward, angleOffset);
|
|
dir.setMag(dist);
|
|
return vec.add(this.pos, dir)
|
|
}
|
|
|
|
follow(targetX, targetY, parentForward = null) {
|
|
let target = new vec(targetX, targetY);
|
|
|
|
let targetForward = vec.sub(target, this.pos);
|
|
let targetAngle = targetForward.heading();
|
|
|
|
if (parentForward) {
|
|
let parentAngle = parentForward.heading();
|
|
let diff = targetAngle - parentAngle;
|
|
|
|
while (diff < -PI) diff += TWO_PI;
|
|
while (diff > PI) diff -= TWO_PI;
|
|
|
|
let maxAngle = PI / 10;
|
|
diff = constrain(diff, -maxAngle, maxAngle);
|
|
|
|
targetAngle = parentAngle + diff;
|
|
}
|
|
|
|
this.forward = p5.Vector.fromAngle(targetAngle);
|
|
|
|
let segmentLength = 20;
|
|
let dir = p5.Vector.mult(this.forward, -segmentLength);
|
|
this.pos = vec.add(target, dir);
|
|
}
|
|
}
|
|
|
|
var n = 0;
|
|
var sizes = [60, 55, 50, 40, 45, 47, 50, 45, 42, 39, 35, 30, 25, 22, 17, 13, ]
|
|
var segments = [];
|
|
function setup() {
|
|
createCanvas(800, 800);
|
|
n = sizes.length;
|
|
for (let i = 0; i < n; i++) {
|
|
let seg = new Segment(400, 400, sizes[i]);
|
|
segments.push(seg);
|
|
}
|
|
|
|
}
|
|
|
|
function draw() {
|
|
background(150);
|
|
|
|
// fisica
|
|
segments[0].follow(mouseX, mouseY);
|
|
for (let i = 1; i < n; i++) {
|
|
let prev_seg = segments[i - 1];
|
|
segments[i].follow(prev_seg.pos.x, prev_seg.pos.y, prev_seg.forward);
|
|
}
|
|
|
|
// dibujar
|
|
fill(249, 182, 249);
|
|
stroke(0);
|
|
strokeWeight(2);
|
|
|
|
beginShape();
|
|
|
|
let head = segments[0];
|
|
let tail = segments[n - 1];
|
|
|
|
for (let a = -HALF_PI; a <= HALF_PI; a += PI / 10) {
|
|
let p = head.get_rel(a, head.size);
|
|
vertex(p.x, p.y);
|
|
}
|
|
|
|
for (let i = 1; i < n - 1; i++) {
|
|
let p = segments[i].get_rel(HALF_PI, segments[i].size);
|
|
vertex(p.x, p.y);
|
|
}
|
|
|
|
for (let a = HALF_PI; a <= HALF_PI + PI; a += PI / 10) {
|
|
let p = tail.get_rel(a, tail.size);
|
|
vertex(p.x, p.y);
|
|
}
|
|
|
|
for (let i = n - 2; i >= 1; i--) {
|
|
let p = segments[i].get_rel(-HALF_PI, segments[i].size);
|
|
vertex(p.x, p.y);
|
|
}
|
|
|
|
|
|
endShape(CLOSE);
|
|
|
|
let eye1 = head.get_rel(HALF_PI / 2, 45);
|
|
let eye2 = head.get_rel(-HALF_PI / 2, 45);
|
|
fill(0);
|
|
circle(eye1.x, eye1.y, 12);
|
|
circle(eye2.x, eye2.y, 12);
|
|
}
|