diff --git a/sketch.js b/sketch.js index 969e364..3dad2d8 100644 --- a/sketch.js +++ b/sketch.js @@ -4,55 +4,46 @@ class Leg { constructor() { this.base = new vec(0, 0); this.end = new vec(0, 0); - this.ikJoint = new IKJoint(4, 30); + this.interPos = new vec(0, 0); + this.ikJoint = new IKJoint(8, 8); + this.repositionDist = 50; + this.moveSpeed = 0.4; } moveTo(startX, startY, endX, endY) { this.base = new vec(startX, startY); let target = new vec(endX, endY); - - if (vec.dist(target, this.end) > 80) { + + if (vec.dist(target, this.end) > this.repositionDist) { this.end = new vec(endX, endY); } - this.ikJoint.moveTo(startX, startY, this.end.x, this.end.y); + this.interPos.lerp(this.end, this.moveSpeed); + this.ikJoint.moveTo(startX, startY, this.interPos.x, this.interPos.y); } getPoints() { return this.ikJoint.points; } - - draw() { - let points = this.ikJoint.points; - let numPts = points.length; - let px = this.base.x; - let py = this.base.y; - - for (let i = 0; i < numPts; i++) { - let pt = points[i]; - line(px, py, pt.pos.x, pt.pos.y); - px = pt.pos.x; - py = pt.pos.y; - } - } } class IKJoint { - constructor(numPoints, pointDist) { + constructor(numSegments, pointDist) { this.origin = new vec(0, 0); this.points = []; - for (let i = 0; i < numPoints + 1; i++) { - this.points.push(new ConstraintPoint(0, 0, pointDist, 10)); + for (let i = 0; i < numSegments + 1; i++) { + this.points.push(new ConstraintPoint(0, 0, pointDist, 0.5)); } this.pointDist = pointDist; - this.iterations = 15; + this.iterations = 20; } moveStart(targetX, targetY) { let numPts = this.points.length; - this.points[0].pos.x = targetX; - this.points[0].pos.y = targetY; + 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]; this.points[i].follow(prevPoint.pos.x, prevPoint.pos.y, prevPoint.forward); @@ -63,13 +54,15 @@ class IKJoint { let numPts = this.points.length; this.points[numPts - 1].pos.x = targetX; this.points[numPts - 1].pos.y = targetY; - + // this.points[numPts - 1].size = 1; + // this.points[numPts - 1].follow(targetX, targetY); + for (let i = numPts - 2; i >= 0; i--) { let prevPoint = this.points[i + 1]; - this.points[i].follow(prevPoint.pos.x, prevPoint.pos.y, prevPoint.forward); + this.points[i].follow(prevPoint.pos.x, prevPoint.pos.y, null); } } - + moveTo(origX, origY, targetX, targetY) { for (let i = 0; i < this.iterations; i++) { this.moveEnd(targetX, targetY); @@ -91,7 +84,7 @@ class ConstraintPoint { 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); @@ -104,7 +97,7 @@ class ConstraintPoint { while (diff < -PI) diff += TWO_PI; while (diff > PI) diff -= TWO_PI; - let maxAngle = this.angleConstraint; + let maxAngle = this.angleConstraint; diff = constrain(diff, -maxAngle, maxAngle); targetAngle = parentAngle + diff; @@ -118,7 +111,8 @@ class ConstraintPoint { } let numPoints = 0; -const sizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13]; +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(); @@ -127,7 +121,7 @@ const leg4 = new Leg(); function setup() { createCanvas(800, 800); - numPoints = sizes.length; + numPoints = bodySizes.length; for (let i = 0; i < numPoints; i++) { let pt = new ConstraintPoint(400, 400, 20); bodyPoints.push(pt); @@ -164,34 +158,80 @@ function drawPoints(points, sizes) { } +function drawGills(basePoint, sign) { + push(); + + let p = basePoint.getRel(sign * 1.5* PI, 35); + translate(p.x, p.y); + rotate(basePoint.forward.heading() + 0.7 * sign); + + strokeWeight(4); + stroke(0); + fill(243, 158, 189); + + for (let i = -1; i <= 1; i++) { + push(); + rotate(i * QUARTER_PI); + ellipse(-10, 0, 80, 30); + pop(); + } + noStroke(); + + for (let i = -1; i <= 1; i++) { + push(); + rotate(i * QUARTER_PI); + ellipse(-10, 0, 80, 30); + pop(); + } + fill(249, 182, 249); + ellipse(16, 0, 40, 55); + + pop(); +} + +let mouseInter = new vec(0, 0); function draw() { background(150); - + + mouseInter.lerp(new vec(mouseX, mouseY), 0.1); + // fisica - bodyPoints[0].follow(mouseX, mouseY); + 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 baseJoint = bodyPoints[2]; - let baseL1 = baseJoint.getRel(-HALF_PI, 20); - let endL1 = baseJoint.getRel(-HALF_PI, 100); - let baseR1 = baseJoint.getRel(HALF_PI, 20); - let endR1 = baseJoint.getRel(HALF_PI, 100); + let legEndDist = 70; + let baseJointL1 = bodyPoints[2]; + let baseL1 = baseJointL1.getRel(-HALF_PI, 30); + let endL1 = baseJointL1.getRel(-HALF_PI, legEndDist); + let baseR1 = baseJointL1.getRel(HALF_PI, 30); + let endR1 = baseJointL1.getRel(HALF_PI, legEndDist); + + let baseJointL2 = bodyPoints[7]; + let baseL2 = baseJointL2.getRel(-HALF_PI, 30); + let endL2 = baseJointL2.getRel(-HALF_PI, legEndDist); + let baseR2 = baseJointL2.getRel(HALF_PI, 30); + let endR2 = baseJointL2.getRel(HALF_PI, legEndDist); leg1.moveTo(baseL1.x, baseL1.y, endL1.x, endL1.y); leg2.moveTo(baseR1.x, baseR1.y, endR1.x, endR1.y); + leg3.moveTo(baseL2.x, baseL2.y, endL2.x, endL2.y); + leg4.moveTo(baseR2.x, baseR2.y, endR2.x, endR2.y); // dibujar fill(249, 182, 249); stroke(0); strokeWeight(2); - - leg2.draw(); + drawPoints(leg1.getPoints(), legSizes); + drawPoints(leg2.getPoints(), legSizes); + drawPoints(leg3.getPoints(), legSizes); + drawPoints(leg4.getPoints(), legSizes); - drawPoints(leg1.getPoints(), [20, 17, 15, 10, 5]); - drawPoints(bodyPoints, sizes); + drawPoints(bodyPoints, bodySizes); + drawGills(bodyPoints[2], 1); + drawGills(bodyPoints[2], -1); let eye1 = bodyPoints[0].getRel(HALF_PI / 2, 45); let eye2 = bodyPoints[0].getRel(-HALF_PI / 2, 45);