如何使用 p5.js 在微观层面模拟刚体?

问题描述 投票:0回答:1

我刚刚了解到,从另一个粒子的参考系(同一物体)观察时,刚体的任何粒子都只执行圆周运动,无论物体遵循什么混沌路径!所以我尝试模拟同样的情况。

我创建了 100 个紧密相连的粒子以形成一个物体,并让它们遵循任意路径,但现在我不知道如何坚持其中一个粒子的参考系并观察其他粒子。 这就是我所做的(我认为没有用):

var path = [];
var particles = [];


class Particle {
  constructor(x_, y_) {
    this.x_ = x_;
    this.y_ = y_;
    this.x = 0;
    this.y = 0;
    this.pathIndex = 0;

    this.draw = () => {
      fill(360, 100, 100);
      circle(this.x, this.y, 1);
    }

    this.update = () => {
      if (this.pathIndex >= path.length) {
        this.pathIndex = 0;
      } else {
        this.x = (path[this.pathIndex].x + this.x_);
        this.y = (path[this.pathIndex].y + this.y_);
        this.pathIndex++;
      }
      this.draw();
    }
  }
}





function setup() {
  createCanvas(400, 400);
  colorMode(HSB);

  for (let i = 0; i < 10; i++) {
    for (let j = 0; j < 10; j++) {
      particles.push(new Particle(i * 2, j * 2));
    }
  }
}

function draw() {
  background(50);

  fill(0);
  noStroke();
  for (let i = 0; i < path.length; i++) {
    circle(path[i].x, path[i].y, 5);
  }
  for (let i = 0; i < particles.length; i++) {
    particles[i].update();

  }
}

function mouseDragged() {
  path.push({
    x: mouseX,
    y: mouseY
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>
单击并拖动以创建路径。

对于真正的刚体,每个粒子都可以有自己的速度,我想我可以使用相对速度概念移动到单个粒子的参考系,然后我可以将其他粒子的速度设置为:

v(1/2) = v1 - v2

其中 v1、v2 是原始速度,v(1/2) 是 1 w.r.t 的速度。 2.
但我又不知道如何获得粒子的速度。

我该如何继续这个操作,非常感谢任何帮助。

javascript physics p5.js
1个回答
0
投票

通常在可视化移动物体时,我们将物体的速度存储在 v_x、v_y 等变量中(就像位置本身一样)。然后更新函数看起来像这样:

this.update = () => {
  this.x += this.v_x;
  this.y += this.v_y;
}

如果物体的速度可以通过力改变,那么加速度(a_x,a_y)应该传递给更新方法(或通过其他计算来计算),如下所示:

this.update = (a_x, a_y) => {
  this.x += this.v_x;
  this.y += this.v_y;
  this.v_x += a_x;
  this.v_y += a_y;
}

但是,就您的情况而言,如果我正确理解您的问题,则无需将速度存储为变量。因此,您只需要知道整体的

x, y, a
,以及粒子的
x, y

const NUM_PARTICLES = 5;
let selectedParticleIdx = 0;
const particle_offsets = [];
let rigidBody;

function setup() {
  createCanvas(400, 400);
  rigidBody  = {
    'x': width / 2,
    'y': height / 2,
    'a': 0,
    'width': width / 2,
    'height': height / 2,
  }
  for (let i=0; i < NUM_PARTICLES; i++) {
    let x_offset = random(rigidBody.width) - rigidBody.width / 2;
    let y_offset = random(rigidBody.height) - rigidBody.height / 2;
    particle_offsets.push([x_offset, y_offset]);
  }
}

您还可以沿着连接它们的线绘制粒子,以显示身体的刚度:

function drawBody() {
  push();
  translate(rigidBody.x, rigidBody.y);
  rotate(rigidBody.a);

  // Draw lines
  for (let i = 0; i < NUM_PARTICLES; i++) {
    let particleX1 = particle_offsets[i][0];
    let particleY1 = particle_offsets[i][1];
    for (let j = i + 1; j < NUM_PARTICLES; j++) {
      let particleX2 = particle_offsets[j][0];
      let particleY2 = particle_offsets[j][1];
      line(particleX1, particleY1, particleX2, particleY2);
    }
  }

  // Draw particles
  for (let i = 0; i < NUM_PARTICLES; i++) {
    let particleX = particle_offsets[i][0];
    let particleY = particle_offsets[i][1];
    ellipse(particleX, particleY, 10, 10); // Adjust the size as needed
  }
  pop();
}

现在,为了展示您刚才谈到的物理概念,我建议在像这样的框中显示粒子 POV:

function showParticlePrespective(coef) {
  push();
  translate(280, 10, 80, 100);
  rect(0, 0, 110, 90);
  translate(55, 45);
  rotate(rigidBody.a);
  let mainParticleX = particle_offsets[0][0];
  let mainParticleY = particle_offsets[0][1];

  // Draw particles
  for (let i = 0; i < NUM_PARTICLES; i++) {
    let particleX = particle_offsets[i][0];
    let particleY = particle_offsets[i][1];
    if (i == selectedParticleIdx) {
      fill('red');
    } else {
      fill('white');
    }
    ellipse((particleX - mainParticleX) / coef, (particleY - mainParticleY) / coef, 2, 2); // Adjust the size as needed
  }
  pop();
}

最后为了移动粒子,您可以在绘图函数中更改其 x,y,a 值:

function draw() {
  background(100); // Set background color
  drawBody(0);
  rigidBody.x += 0.3;
  rigidBody.y += 0.3;
  rigidBody.a += 0.04;
  showParticlePrespective(3);
}

更好的方法是让主体根据用户输入(键盘)更改其

x, y, a
值。

© www.soinside.com 2019 - 2024. All rights reserved.