Silverback9

#야생으로

Creative Coding 독학 제169일 2024년09월12일(목)

먼저 어제 정리한 충돌 표현 코드를 한 곳에 모아보겠습니다. YEAH!!!

함수 collide()! 이름이 마음에 드시나요~~^^*

 collide(other) {

    let impactVector = p5.Vector.sub(other.position, this.position);
    let d = impactVector.mag();
    if (d < this.r + other.r) {
      
      // 겹친 부분 직경의 1/2만큼 각 물체가 뒤로 물러섭니다.
      let overlap = d - (this.r + other.r);
      let dir = impactVector.copy();
      dir.setMag(overlap * 0.5);
      this.position.add(dir);
      other.position.sub(dir);
      
      // 두 물체가 서로 닿을 때 거리와 impactVector 길이값을 재정의합니다.
      d = this.r + other.r;
      impactVector.setMag(d);
      
      let mSum = this.mass + other.mass;
      let vDiff = p5.Vector.sub(other.velocity, this.velocity);
      
      // 물체 this의 속도 변화를 계산합니다. 
      let num = vDiff.dot(impactVector);
      let den = mSum * d * d;
      let deltaVA = impactVector.copy();
      deltaVA.mult(2 * other.mass * num / den);
      this.velocity.add(deltaVA);
      
      // 물체 other의 속도 변화를 계산합니다. 
      let deltaVB = impactVector.copy();
      deltaVB.mult(-2 * this.mass * num / den);
      other.velocity.add(deltaVB);
    }
  }

이제 물체 클래스 정의를 완성하고~~^^* 두 물체를 생성하여 2차원 탄성 충돌을 표현해 볼까요~~^^*

전체 코드 저와 함께 보시죠~~^^*

인덱스 파일에는 물체 클래스 정의 파일을 먼저 넣고, 메인인 스케치 파일을 넣습니다~^^*

<!DOCTYPE html>
<html>
  <head>
    https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.2/p5.min.js
    <meta charset="utf-8" />
    <title>NOC_4_06_ParticlesSystemForces</title>
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
    http://particle.js
    http://sketch.js
  </body>
</html>

네~~^^* 물체 클래스 정의는, 우리에게 익숙한 입자 클래스 정의에, 이번 공부의 핵심! 2차원 탄성 충돌 계산식을 넣은 것이에요~~^^*

class Particle {
  constructor(x, y) {
    this.position = createVector(x, y);
    this.velocity = p5.Vector.random2D();
    this.velocity.mult(random(2, 6));
    this.acceleration = createVector(0, 0);
    this.mass = random(2, 6);
    this.r = sqrt(this.mass) * 20;
    //플레이 버튼을 누를 때마다 속도와 질량이 다른 물체가 생성됩니다. 
  }

  applyForce(force) {
    let f = force.copy();
    f.div(this.mass);
    this.acceleration.add(f);
  }

  update() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
  }

  // 충돌을 탐지하고 해결해 봅시다!!!
  
  collide(other) {

    let impactVector = p5.Vector.sub(other.position, this.position);
    let d = impactVector.mag();
    if (d < this.r + other.r) {
      
     
      let overlap = d - (this.r + other.r);
      let dir = impactVector.copy();
      dir.setMag(overlap * 0.5);
      this.position.add(dir);
      other.position.sub(dir);
      
     
      d = this.r + other.r;
      impactVector.setMag(d);
      
      let mSum = this.mass + other.mass;
      let vDiff = p5.Vector.sub(other.velocity, this.velocity);
     
      let num = vDiff.dot(impactVector);
      let den = mSum * d * d;
      let deltaVA = impactVector.copy();
      deltaVA.mult(2 * other.mass * num / den);
      this.velocity.add(deltaVA);
     
      let deltaVB = impactVector.copy();
      deltaVB.mult(-2 * this.mass * num / den);
      other.velocity.add(deltaVB);
    }
  }

 //벽에 부딪히면 반대방향으로 움직입니다~^^*

  edges() {
    if (this.position.x > width - this.r) {
      this.position.x = width - this.r;
      this.velocity.x *= -1;
    } else if (this.position.x < this.r) {
      this.position.x = this.r;
      this.velocity.x *= -1;
    }

    if (this.position.y > height - this.r) {
      this.position.y = height - this.r;
      this.velocity.y *= -1;
    } else if (this.position.y < this.r) {
      this.position.y = this.r;
      this.velocity.y *= -1;
    }
  }

 //우리 물체를 보여 주세요~~^^*

  show() {
    stroke(0);
    strokeWeight(2);
    fill(127);
    circle(this.position.x, this.position.y, this.r * 2);
  }
}

물체 두 가지를 생성하여 화면에 표현해 봅시다~~!!!


let particleA;
let particleB;

function setup() {
  createCanvas(400, 400);
  particleA = new Particle(320, 60);
  particleB = new Particle(320, 300);
}

function draw() {
  background(255);

  particleA.collide(particleB);

  particleA.update();
  particleB.update();

  particleA.edges();
  particleB.edges();

  particleA.show();
  particleB.show();

  //콘솔 창에 두 물체의 Kinetic Energy 운동에너지를 기록해 볼까요~^^*
  //과연 우리는 탄성 충돌을 표현해 낸 것일까요~~^^*?

  let speedA = particleA.velocity.mag();
  let speedB = particleB.velocity.mag();
  let kinA = 0.5 * particleA.mass * speedA * speedA;
  let kinB = 0.5 * particleB.mass * speedB * speedB;
  console.log(kinA + kinB);
}

드디어~~~^^* 드디어~~~^^* 두 입자가 평면에서 Momentum 운동량과 Kinetic Engergy 운동에너지를 보존하며 서로 충돌하고 이동하고 또 충돌하고 또 이동합니다~~^^* 콘솔창에 기록되는 운동에너지의 값이 항상 일정한지도 관찰해 볼까요~~^^*

운동량 Momentum과 운동에너지 Kinetic Energy 가 항상 Stay the Same 하는 이차원 탄성 충돌 2 Dimensional Elastic Collision을 저와 함께 완성해 주셔서 감사합니다~~^^*

내일은 우리, 여러 개의 물체를 생성하여 서로 충돌하는 프로그램으로 발전시켜 볼까요~~^^*

비가 촉촉하게 내리는 아침이예요~~^^*

우리 가슴 속 꿈이 항상 Stay the Same 할 수 있도록, 오늘도 즐거운 아침! 즐거운 하루! 보내셔요~^^*

네~~!!! 꿈은 이루어 집니다~~!!!

댓글 남기기