Chapter 59

バネ・弾性力

miku
miku
2021.11.16に更新
このチャプターの目次

伸び縮みしていないバネがあり、そのバネの長さを自然長と呼ぶ。縮んだバネや伸びたバネは自然長になるように戻ろうとする力が働く。そのような力を弾性力と呼ぶ。

この力の動きを確認するために、マウス座標と円の間にバネが張られているとする。自然長である len を定義、マウス座標から円までの距離 dist を計算して、d - len で伸び縮みしている変化量を取得する。円からマウス座標までの角度を取得して、その方向に変化量に依存した力を与える。ただし、そのままだと力が大きすぎるので1未満の係数を掛ける必要がある。

const len = 100; // 自然長
const k = 0.0005; // 自然長に戻ろうとする力に掛ける係数
let p, v, a;

function setup() {
  createCanvas(windowWidth, windowHeight);

  p = createVector(width / 2, height / 2);
  v = createVector(0, 0);
  a = createVector(0, 0);
}

function draw() {
  clear();

  const angle = atan2(mouseY - p.y, mouseX - p.x);
  const d = dist(mouseX, mouseY, p.x, p.y);
  const diff = d - len;
  a = p5.Vector.fromAngle(angle, diff * k);

  v.add(a);
  p.add(v);

  stroke(240);
  noFill();
  line(mouseX, mouseY, p.x, p.y);

  noStroke();
  fill(240);
  circle(p.x, p.y, 50);

  stroke(240);
  noFill();
  line(mouseX - 10, mouseY, mouseX + 10, mouseY);
  line(mouseX, mouseY - 10, mouseX, mouseY + 10);
}

速度を減衰させる

現実では空気抵抗などにより速度が少しずつ落ちていくので、それを表現するために毎フレーム1未満の係数を速度に掛け合わせる。

const len = 100;
const k = 0.0005;
const vk = 0.99;
let p, v, a;

function setup() {
  createCanvas(windowWidth, windowHeight);

  p = createVector(width / 2, height / 2);
  v = createVector(0, 0);
  a = createVector(0, 0);
}

function draw() {
  clear();

  const angle = atan2(mouseY - p.y, mouseX - p.x);
  const d = dist(mouseX, mouseY, p.x, p.y);
  const diff = d - len;
  a = p5.Vector.fromAngle(angle, diff * k);

  v.add(a);
  v.mult(vk);
  p.add(v);

  stroke(240);
  noFill();
  line(mouseX, mouseY, p.x, p.y);

  noStroke();
  fill(240);
  circle(p.x, p.y, 50);

  stroke(240);
  noFill();
  line(mouseX - 10, mouseY, mouseX + 10, mouseY);
  line(mouseX, mouseY - 10, mouseX, mouseY + 10);
}