refactor, adding legs
This commit is contained in:
parent
ad80077fc7
commit
c0441271b5
1 changed files with 146 additions and 49 deletions
195
sketch.js
195
sketch.js
|
|
@ -1,21 +1,99 @@
|
||||||
var vec = p5.Vector;
|
const vec = p5.Vector;
|
||||||
|
|
||||||
class Segment {
|
class Leg {
|
||||||
constructor(x, y, size) {
|
constructor() {
|
||||||
|
this.base = new vec(0, 0);
|
||||||
|
this.end = new vec(0, 0);
|
||||||
|
this.ikJoint = new IKJoint(4, 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
moveTo(startX, startY, endX, endY) {
|
||||||
|
this.base = new vec(startX, startY);
|
||||||
|
let target = new vec(endX, endY);
|
||||||
|
|
||||||
|
if (vec.dist(target, this.end) > 80) {
|
||||||
|
this.end = new vec(endX, endY);
|
||||||
|
}
|
||||||
|
this.ikJoint.moveTo(startX, startY, this.end.x, this.end.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) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
this.pointDist = pointDist;
|
||||||
|
this.iterations = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveStart(targetX, targetY) {
|
||||||
|
let numPts = this.points.length;
|
||||||
|
this.points[0].pos.x = targetX;
|
||||||
|
this.points[0].pos.y = targetY;
|
||||||
|
this.points[0].follow(targetX, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveEnd(targetX, targetY) {
|
||||||
|
let numPts = this.points.length;
|
||||||
|
this.points[numPts - 1].pos.x = targetX;
|
||||||
|
this.points[numPts - 1].pos.y = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveTo(origX, origY, targetX, targetY) {
|
||||||
|
for (let i = 0; i < this.iterations; i++) {
|
||||||
|
this.moveEnd(targetX, targetY);
|
||||||
|
this.moveStart(origX, origY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConstraintPoint {
|
||||||
|
constructor(x, y, size, angleConstraint = 0.2) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.pos = new vec(x, y);
|
this.pos = new vec(x, y);
|
||||||
this.forward = new vec(0, 0);
|
this.forward = new vec(0, 0);
|
||||||
|
this.angleConstraint = angleConstraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_rel(angleOffset, dist) {
|
getRel(angleOffset, dist) {
|
||||||
let dir = vec.rotate(this.forward, angleOffset);
|
let dir = vec.rotate(this.forward, angleOffset);
|
||||||
dir.setMag(dist);
|
dir.setMag(dist);
|
||||||
return vec.add(this.pos, dir)
|
return vec.add(this.pos, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
follow(targetX, targetY, parentForward = null) {
|
follow(targetX, targetY, parentForward = null) {
|
||||||
let target = new vec(targetX, targetY);
|
let target = new vec(targetX, targetY);
|
||||||
|
|
||||||
let targetForward = vec.sub(target, this.pos);
|
let targetForward = vec.sub(target, this.pos);
|
||||||
let targetAngle = targetForward.heading();
|
let targetAngle = targetForward.heading();
|
||||||
|
|
||||||
|
|
@ -26,7 +104,7 @@ class Segment {
|
||||||
while (diff < -PI) diff += TWO_PI;
|
while (diff < -PI) diff += TWO_PI;
|
||||||
while (diff > PI) diff -= TWO_PI;
|
while (diff > PI) diff -= TWO_PI;
|
||||||
|
|
||||||
let maxAngle = PI / 10;
|
let maxAngle = this.angleConstraint;
|
||||||
diff = constrain(diff, -maxAngle, maxAngle);
|
diff = constrain(diff, -maxAngle, maxAngle);
|
||||||
|
|
||||||
targetAngle = parentAngle + diff;
|
targetAngle = parentAngle + diff;
|
||||||
|
|
@ -34,70 +112,89 @@ class Segment {
|
||||||
|
|
||||||
this.forward = p5.Vector.fromAngle(targetAngle);
|
this.forward = p5.Vector.fromAngle(targetAngle);
|
||||||
|
|
||||||
let segmentLength = 20;
|
let dir = p5.Vector.mult(this.forward, -this.size);
|
||||||
let dir = p5.Vector.mult(this.forward, -segmentLength);
|
|
||||||
this.pos = vec.add(target, dir);
|
this.pos = vec.add(target, dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var n = 0;
|
let numPoints = 0;
|
||||||
var sizes = [60, 55, 50, 40, 45, 47, 50, 45, 42, 39, 35, 30, 25, 22, 17, 13, ]
|
const sizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13];
|
||||||
var segments = [];
|
const bodyPoints = [];
|
||||||
|
const leg1 = new Leg();
|
||||||
|
const leg2 = new Leg();
|
||||||
|
const leg3 = new Leg();
|
||||||
|
const leg4 = new Leg();
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
createCanvas(800, 800);
|
createCanvas(800, 800);
|
||||||
n = sizes.length;
|
numPoints = sizes.length;
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i = 0; i < numPoints; i++) {
|
||||||
let seg = new Segment(400, 400, sizes[i]);
|
let pt = new ConstraintPoint(400, 400, 20);
|
||||||
segments.push(seg);
|
bodyPoints.push(pt);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawPoints(points, sizes) {
|
||||||
|
beginShape();
|
||||||
|
|
||||||
|
let numPoints = points.length;
|
||||||
|
let head = points[0];
|
||||||
|
let tail = points[numPoints - 1];
|
||||||
|
|
||||||
|
for (let angle = -HALF_PI; angle <= HALF_PI; angle += PI / 10) {
|
||||||
|
let p = head.getRel(angle, sizes[0]);
|
||||||
|
vertex(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = numPoints - 2; i >= 1; i--) {
|
||||||
|
let p = points[i].getRel(-HALF_PI, sizes[i]);
|
||||||
|
vertex(p.x, p.y);
|
||||||
|
}
|
||||||
|
endShape(CLOSE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
background(150);
|
background(150);
|
||||||
|
|
||||||
// fisica
|
// fisica
|
||||||
segments[0].follow(mouseX, mouseY);
|
bodyPoints[0].follow(mouseX, mouseY);
|
||||||
for (let i = 1; i < n; i++) {
|
for (let i = 1; i < numPoints; i++) {
|
||||||
let prev_seg = segments[i - 1];
|
let prevPoint = bodyPoints[i - 1];
|
||||||
segments[i].follow(prev_seg.pos.x, prev_seg.pos.y, prev_seg.forward);
|
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);
|
||||||
|
|
||||||
|
leg1.moveTo(baseL1.x, baseL1.y, endL1.x, endL1.y);
|
||||||
|
leg2.moveTo(baseR1.x, baseR1.y, endR1.x, endR1.y);
|
||||||
|
|
||||||
// dibujar
|
// dibujar
|
||||||
fill(249, 182, 249);
|
fill(249, 182, 249);
|
||||||
stroke(0);
|
stroke(0);
|
||||||
strokeWeight(2);
|
strokeWeight(2);
|
||||||
|
|
||||||
beginShape();
|
|
||||||
|
|
||||||
let head = segments[0];
|
leg2.draw();
|
||||||
let tail = segments[n - 1];
|
|
||||||
|
|
||||||
for (let a = -HALF_PI; a <= HALF_PI; a += PI / 10) {
|
drawPoints(leg1.getPoints(), [20, 17, 15, 10, 5]);
|
||||||
let p = head.get_rel(a, head.size);
|
drawPoints(bodyPoints, sizes);
|
||||||
vertex(p.x, p.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 1; i < n - 1; i++) {
|
let eye1 = bodyPoints[0].getRel(HALF_PI / 2, 45);
|
||||||
let p = segments[i].get_rel(HALF_PI, segments[i].size);
|
let eye2 = bodyPoints[0].getRel(-HALF_PI / 2, 45);
|
||||||
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);
|
fill(0);
|
||||||
circle(eye1.x, eye1.y, 12);
|
circle(eye1.x, eye1.y, 12);
|
||||||
circle(eye2.x, eye2.y, 12);
|
circle(eye2.x, eye2.y, 12);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue