具有任意数量点的逆运动学

时间:2016-03-08 01:08:06

标签: javascript html5 canvas inverse-kinematics

我使用HTML5 Canvas在JavaScript中修改了this反向运动学的示例,并通过将其分离为函数使其动态化,并且它可以工作,但该示例仅使用3个点 - 开始,中间,并结束,我想随意改变点数。这是我目前的fiddle ...

function _kinematics(joints, fx, mouse) {
  joints.forEach(function (joint) {
    joint.target = joint.target || {
      x: fx.canvas.width / 2,
      y: fx.canvas.height / 2
    };
    joint.start = joint.start || {
      x: 0,
      y: 0
    };
    joint.middle = joint.middle || {
      x: 0,
      y: 0
    };
    joint.end = joint.end || {
      x: 0,
      y: 0
    };
    joint.length = joint.length || 50;
  });
  var theta,
    $theta,
    _theta,
    dx,
    dy,
    distance;
  joints.forEach(function (joint) {
    if (mouse) {
      joint.target.x = mouse.x;
      joint.target.y = mouse.y;
    }
    dx = joint.target.x - joint.start.x;
    dy = joint.target.y - joint.start.y;
    distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
    _theta = Math.atan2(dy, dx);
    if (distance < joint.length) {
      theta = Math.acos(distance / (joint.length + joint.length)) + _theta;
      dx = dx - joint.length * Math.cos(theta);
      dy = dy - joint.length * Math.sin(theta);
      $theta = Math.atan2(dy, dx);
    } else {
      theta = $theta = _theta;
    }
    joint.middle.x = joint.start.x + Math.cos(theta) * joint.length;
    joint.middle.y = joint.start.y + Math.sin(theta) * joint.length;
    joint.end.x = joint.middle.x + Math.cos($theta) * joint.length;
    joint.end.y = joint.middle.y + Math.sin($theta) * joint.length;
    fx.beginPath();
    fx.moveTo(joint.start.x, joint.start.y);
    /* for (var i = 0; i < joint.points.length / 2; i++) {
        fx.lineTo(joint.points[i].x, joint.points[i].y);
    } */
    fx.lineTo(joint.middle.x, joint.middle.y);
    /* for (var j = joint.points.length / 2; j < joint.points.length; j++) {
        fx.lineTo(joint.points[j].x, joint.points[j].y);
    } */
    fx.lineTo(joint.end.x, joint.end.y);
    fx.strokeStyle = "rgba(0,0,0,0.5)";
    fx.stroke();
    fx.beginPath();
    fx.arc(joint.start.x, joint.start.y, 10, 0, Math.PI * 2);
    fx.fillStyle = "rgba(255,0,0,0.5)";
    fx.fill();
    fx.beginPath();
    fx.arc(joint.middle.x, joint.middle.y, 10, 0, Math.PI * 2);
    fx.fillStyle = "rgba(0,255,0,0.5)";
    fx.fill();
    fx.beginPath();
    fx.arc(joint.end.x, joint.end.y, 10, 0, Math.PI * 2);
    fx.fillStyle = "rgba(0,0,255,0.5)";
    fx.fill();
  });
}

这只是功能,为了简洁,我省略了其余部分。正如你所看到的,注释掉的线条是我试图绘制其他点。

此外,我在这里使用点等填充joints数组。请参阅注释行。

populate(_joints, $joints, function() {
  var coords = randCoords(map);
  var o = {
    start: {
      x: coords.x,
      y: coords.y
    },
    // points: [],
    target: {
      x: mouse.x,
      y: mouse.y
    }
  };
  /* for (var p = 0; p < 10; p++) {
    o.points.push({
      x: p === 0 ? o.start.x + (o.length || 50) : o.points[p - 1].x + (o.length || 50),
      y: p === 0 ? o.start.y + (o.length || 50) : o.points[p - 1].y + (o.length || 50)
    });
  }; */
  return o;
});

如何使此功能与 n 点一起使用?

0 个答案:

没有答案