diff --git a/chain1.js b/chain1.js new file mode 100644 index 0000000..181f9d7 --- /dev/null +++ b/chain1.js @@ -0,0 +1,47 @@ +let vec = p5.Vector + +class ConstraintPoint { + constructor(x, y, size) { + this.size = size; + this.pos = new vec(x, y); + this.forward = new vec(0, 0); + } + + follow(targetX, targetY) { + let target = new vec(targetX, targetY); + let targetForward = vec.sub(target, this.pos); + let targetAngle = targetForward.heading(); + + this.forward = p5.Vector.fromAngle(targetAngle); + + let dir = p5.Vector.mult(this.forward, -this.size); + this.pos = vec.add(target, dir); + + + } +} + +let points = [] +function setup() { + createCanvas(400, 400); + + for (let i = 0;i < 10;i++) { + points.push(new ConstraintPoint(0, 0, 20)); + } +} + + +function draw() { + background(220); + + points[0].follow(mouseX, mouseY) + for (let i = 1;i < 10;i++) { + let prev = points[i - 1]; + points[i].follow(prev.pos.x, prev.pos.y); + } + for (let i = 1;i < 10;i++) { + let pos = points[i].pos; + noFill(); + circle(pos.x, pos.y, 40); + } +} diff --git a/chain2.js b/chain2.js new file mode 100644 index 0000000..c53aaa3 --- /dev/null +++ b/chain2.js @@ -0,0 +1,58 @@ +let vec = p5.Vector + +class ConstraintPoint { + constructor(x, y, size) { + this.size = size; + this.pos = new vec(x, y); + this.forward = new vec(0, 0); + } + + follow(targetX, targetY, prevForward = null) { + let target = new vec(targetX, targetY); + let targetForward = vec.sub(target, this.pos); + let targetAngle = targetForward.heading(); + + + + if (prevForward) { + let a = targetAngle - prevForward; + while (a > PI) { a -= TWO_PI; } + while (a < -PI) { a += TWO_PI; } + + a = constrain(a, -0.3, 0.3); + + targetAngle = prevForward + a; + } + + this.forward = vec.fromAngle(targetAngle); + let dir = vec.mult(this.forward, -this.size); + this.pos = vec.add(target, dir); + + + } +} + +let points = [] +function setup() { + createCanvas(400, 400); + + for (let i = 0;i < 10;i++) { + points.push(new ConstraintPoint(0, 0, 20)); + } +} + + +function draw() { + background(220); + + points[0].follow(mouseX, mouseY) + for (let i = 1;i < 10;i++) { + let prev = points[i - 1]; + points[i].follow(prev.pos.x, prev.pos.y, prev.forward.heading()); + } + for (let i = 0;i < 10;i++) { + let pos = points[i].pos; + noFill(); + circle(pos.x, pos.y, 40); + } +} diff --git a/chain3.js b/chain3.js new file mode 100644 index 0000000..28b0fe6 --- /dev/null +++ b/chain3.js @@ -0,0 +1,84 @@ +let vec = p5.Vector + + +class ConstraintPoint { + constructor(x, y, size) { + this.size = size; + this.pos = new vec(x, y); + this.forward = new vec(0, 0); + } + + follow(targetX, targetY, prevForward = null) { + let target = new vec(targetX, targetY); + let targetForward = vec.sub(target, this.pos); + let targetAngle = targetForward.heading(); + + + + if (prevForward) { + let a = targetAngle - prevForward; + while (a > PI) { a -= TWO_PI; } + while (a < -PI) { a += TWO_PI; } + + a = constrain(a, -0.3, 0.3); + + targetAngle = prevForward + a; + } + + this.forward = vec.fromAngle(targetAngle); + let dir = vec.mult(this.forward, -this.size); + this.pos = vec.add(target, dir); + } + + getRel(a, dist) { + return vec.add(this.pos, vec.mult(vec.fromAngle(this.forward.heading() + a), dist)); + } +} + +let points = [] +let sizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13] +function setup() { + createCanvas(400, 400); + + for (let i = 0;i < sizes.length;i++) { + points.push(new ConstraintPoint(0, 0, 20)); + } +} + +function drawPoints(points, sizes) { + beginShape(); + for (let a = -HALF_PI;a < HALF_PI;a+=0.1) { + let p = points[0].getRel(a, sizes[0]) + vertex(p.x, p.y); + } + for (let i = 0;i < points.length;i++) { + let p = points[i].getRel(HALF_PI, sizes[i]) + vertex(p.x, p.y); + } + + for (let a = HALF_PI;a < HALF_PI + PI;a+=0.1) { + let p = points[points.length -1].getRel(a, sizes[points.length -1]) + vertex(p.x, p.y); + } + + for (let i = points.length-1;i >= 0;i--) { + let p = points[i].getRel(-HALF_PI, sizes[i]) + vertex(p.x, p.y); + } + + endShape(); +} + + +function draw() { + background(220); + + points[0].follow(mouseX, mouseY) + for (let i = 1;i < sizes.length;i++) { + let prev = points[i - 1]; + points[i].follow(prev.pos.x, prev.pos.y, prev.forward.heading()); + } + + fill(255) + drawPoints(points, sizes); +} diff --git a/index.html b/index.html index 72fcde0..29549f6 100644 --- a/index.html +++ b/index.html @@ -4,11 +4,10 @@ - Sketch - - + Procedural Animation + diff --git a/sketch.js b/sketch.js index e023a06..a9791c5 100644 --- a/sketch.js +++ b/sketch.js @@ -41,8 +41,6 @@ class IKJoint { let numPts = this.points.length; this.points[0].size = 1; this.points[0].follow(targetX, targetY); - // this.points[0].pos.x = targetX; - // this.points[0].pos.y = targetY; for (let i = 1; i < numPts; i++) { let prevPoint = this.points[i - 1]; @@ -110,24 +108,6 @@ class ConstraintPoint { } } -let numPoints = 0; -const bodySizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13]; -const legSizes = Array.from({ length: 20 }, () => 15); -const bodyPoints = []; -const leg1 = new Leg(); -const leg2 = new Leg(); -const leg3 = new Leg(); -const leg4 = new Leg(); - -function setup() { - createCanvas(800, 800); - numPoints = bodySizes.length; - for (let i = 0; i < numPoints; i++) { - let pt = new ConstraintPoint(400, 400, 20); - bodyPoints.push(pt); - } -} - function drawPoints(points, sizes) { beginShape(); @@ -137,22 +117,22 @@ function drawPoints(points, sizes) { for (let angle = -HALF_PI; angle <= HALF_PI; angle += PI / 10) { let p = head.getRel(angle, sizes[0]); - vertex(p.x, p.y); + curveVertex(p.x, p.y); } for (let i = 1; i < numPoints - 1; i++) { let p = points[i].getRel(HALF_PI, sizes[i]); - vertex(p.x, p.y); + curveVertex(p.x, p.y); } for (let angle = HALF_PI; angle <= HALF_PI + PI; angle += PI / 10) { let p = tail.getRel(angle, sizes[numPoints - 1]); - vertex(p.x, p.y); + curveVertex(p.x, p.y); } for (let i = numPoints - 2; i >= 1; i--) { let p = points[i].getRel(-HALF_PI, sizes[i]); - vertex(p.x, p.y); + curveVertex(p.x, p.y); } endShape(CLOSE); @@ -161,7 +141,7 @@ function drawPoints(points, sizes) { function drawGills(basePoint, sign) { push(); - let p = basePoint.getRel(sign * 1.5* PI, 35); + let p = basePoint.getRel(sign * 1.5 * PI, 35); translate(p.x, p.y); rotate(basePoint.forward.heading() + 0.7 * sign); @@ -189,17 +169,47 @@ function drawGills(basePoint, sign) { pop(); } +let numPoints = 0; +const bodySizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13]; +const legSizes = Array.from({ length: 20 }, () => 15); +const bodyPoints = []; +const leg1 = new Leg(); +const leg2 = new Leg(); +const leg3 = new Leg(); +const leg4 = new Leg(); let mouseInter = new vec(0, 0); + +function setup() { + createCanvas(displayWidth, displayHeight); + numPoints = bodySizes.length; + for (let i = 0; i < numPoints; i++) { + let pt = new ConstraintPoint(400, 400, 20); + bodyPoints.push(pt); + } +} + function draw() { background(150); - mouseInter.lerp(new vec(mouseX, mouseY), 0.1); + mouseInter.lerp(new vec(mouseX, mouseY), 0.01); + let time = millis(); // fisica bodyPoints[0].follow(mouseInter.x, mouseInter.y); + for (let i = 1; i < numPoints; i++) { let prevPoint = bodyPoints[i - 1]; bodyPoints[i].follow(prevPoint.pos.x, prevPoint.pos.y, prevPoint.forward); + + let tailStart = Math.floor(numPoints / 2); + if (i > tailStart) { + let wiggleIntensity = map(i, tailStart, numPoints - 1, 0, 4); + + let wiggleAmount = sin(time * 0.004 - i * 0.5) * wiggleIntensity; + + let lateralDir = vec.rotate(bodyPoints[i].forward, HALF_PI); + bodyPoints[i].pos.add(p5.Vector.mult(lateralDir, wiggleAmount)); + } } let legEndDist = 70; let baseJointL1 = bodyPoints[2]; @@ -208,7 +218,7 @@ function draw() { let baseR1 = baseJointL1.getRel(HALF_PI, 30); let endR1 = baseJointL1.getRel(HALF_PI, legEndDist); - let baseJointL2 = bodyPoints[7]; + let baseJointL2 = bodyPoints[6]; let baseL2 = baseJointL2.getRel(-HALF_PI, 30); let endL2 = baseJointL2.getRel(-HALF_PI, legEndDist); let baseR2 = baseJointL2.getRel(HALF_PI, 30); @@ -229,18 +239,27 @@ function draw() { drawPoints(leg3.getPoints(), legSizes); drawPoints(leg4.getPoints(), legSizes); - drawPoints(bodyPoints, bodySizes); + let currentBodySizes = [...bodySizes]; + let breathSpeed = time * 0.003; + + for (let i = 0; i < numPoints; i++) { + let centerWeight = sin(map(i, 0, numPoints - 1, 0, PI)); + + let breathExpansion = sin(breathSpeed) * 1 * centerWeight + 1; + currentBodySizes[i] += breathExpansion; + } + + drawPoints(bodyPoints, currentBodySizes); let p1 = bodyPoints[4].pos; let p2 = bodyPoints[6].pos; let p3 = bodyPoints[8].pos; let p4 = bodyPoints[10].pos; push(); - // noStroke(); + noStroke(); fill(243, 158, 189); bezier(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y); pop(); - // line(p1.x, p1.y, p4.x, p4.y); drawGills(bodyPoints[2], 1); drawGills(bodyPoints[2], -1);