Silverback9

#야생으로

Creative Coding 독학 제094일 2024년06월29일(토)

오늘은 다섯 명의 피겨 스케이팅 꿈나무들이 한 줄로 나란히 빙판 위를 움직이는 연습을 하는 모습을 프로그램으로 표현해 보겠습니다~^^*

아래 동영상을 클릭하시면 오늘 공부 내용을 바로 시작(24:17)하실 수 있어요~^^* 27:12까지 보시면 오늘 공부 끝~~^^*

다섯 명의 스케이터라…

그러면 입자가 5개나 되는데…

그렇다면…!!!

그렇죠!!! 입자 배열을 만들어 사용해 봅시다!!!

스케이트 꿈나무들이 나란히 움직이려면…

그렇다면….!!!

그렇죠!!! 입자와 입자 사이에 스프링을 연결해 봅시다!!!

그러면…스프링이 여러 개 필요한데….

그렇다면…!!!

그렇죠!!! 스프링 배열을 만들어 사용해 봅시다!!!

스케이트 꿈나무들이 원을 지어 돌아다니지 않고, 한 줄로 나란히 움직이려면…

입자와 그 앞에 있는 입자를 스프링으로 연결하면 되는데, 맨 앞의 입자는 연결될 앞의 입자가 없는데…

그렇다면…!!!

그렇죠!!! 맨 앞의 입자는 스프링을 사용하지 않으면 되겠군요!!!

그렇다면…!!!

네!!! 스프링이 총 4개 필요하겠어요!!!

와우!!! 이제 아이디어는 잘 다듬어 진 것 같은데요~^^* 수고 많으셨어요~~!!!

함께 궁리해 주셔서 감사합니다~~~!!!

그럼 본격적으로 코딩을 해 볼게요~~^^*

class Particle과 class Spring은, 오늘은 코드 내용 변화가 없겠지만, 기본 객체로 계속 사용하니까, 복습 겸~^^*, 코드 내용을 한 번 더 살펴 볼게요~^^*

오늘 공부 내용의 하이라이트는 메인 파일인 sketch.js에 담겨 있습니다~^^*

<!DOCTYPE html>
<html lang="en">
  <head>
    https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.js
    https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/addons/p5.sound.min.js
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <main>
    </main>
    http://spring.js
    http://particle.js
    http://sketch.js
  </body>
</html>
class Particle{
  constructor(x,y){
    this.acceleration = createVector(0,0);
    this.velocity = createVector(0,0);
    this.position = createVector(x,y);
    this.mass = 1;
  }
  applyForce(force){
    let f = force.copy();
    f.div(this.mass);
    this.acceleration.add(f);
    // F = M * A를 적용하여, A = F / M 관계를 사용합니다.
    // f = F / M 하여, f를 가속도에 더합니다.  
  }
  update() {
    this.velocity.mult(0.99);
    //빙판 위의 마찰력을 반영하여, 입자의 운동속도를 점차 줄여나가겠습니다. 
    
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
    // 가속도가 속도에 영향을 주고
    // 속도가 위치에 영향을 준 뒤
    // 가속도는 0로 재세팅합니다. 
    // 함수 draw()는 무한반복하기 때문에, 가속도가 force의 변화가 없는데도 중첩증가하지 않는 장치가 필요합니다: 가속도 재세팅!  
  }
  show(){
    stroke(255);
    strokeWeight(4);
    fill(127, 255, 127);
    ellipse(this.position.x, this.position.y, 12);
    //피겨 스케이트 선수들은 날씬하니까, 입자 크기를 작게 만들어 보겠습니다. 
  }
}
class Spring {
  constructor(k, restLength, a, b){
    this.k = k;
    this.restLength = restLength;
    this.a = a;
    this.b = b;  
  }
  update(){
    
    let force = p5.Vector.sub(this.b.position, this.a.position);
    // 벡터 b 입자에서 벡터 a 입자를 뺍니다.
    // 벡터 force의 방향은 입자 a에서 입자 b으로 향합니다. 
    
    let x = force.mag() - this.restLength;
    force.normalize();
    
    force.mult(this.k*x);
    this.a.applyForce(force);
    // 벡터 force의 방향이 이미 입자 a에서 입자 b로 향하고 있으므로, 탄성계수 k * 거리 x를 그대로 씁니다. 
    // 입자 a가 입자 b로 향하는 힘입니다. 
    
    force.mult(-1);
    this.b.applyForce(force);
    //입자 b가 입자 a로 향하는 힘을 표현하기 위해서, 벡터 force에 -1을 곱하여, 힘의 방향을 바꿉니다.
    
    // 두 입자 a, b가 스프링으로 연결되어 서로를 향한 힘을 가지고 있습니다. 
    
  }
  show(){
    strokeWeight(4);
    stroke(255);
    line(this.a.position.x, this.a.position.y, this.b.position.x, this.b.position.y);
  }
}

오늘의 하이라이트! sketch.js 파일 내용입니다~ 주석 내용이 많아, 하이라이트 처리는 하지 않겠습니다~^^*

let particles = [];
let springs = [];
//입자와 스프링은 배열을 만들어 저장해 봅시다~^^*

let k = 0.01;

let spacing = 50;
//처음 시작할 때, 입자들 사이의 수직 거리가 될 것입니다~^^* 
//입자들 사이의 스프링의 원래 길이(restLength)로 사용하겠습니다~^^*

function setup() {
  
  createCanvas(400, 400);
  
  for( let i = 0; i <5; i++){
    // [0] ~ [4] 총 5개의 입자를 만들어 보겠습니다~^^*
    
    particles[i] = new Particle(200, i*spacing);
    // 화면 가운데, 맨 위에서 아래로 spacing = 50 간격으로 수직으로 나란히 위치시켜 볼게요~^^*
    
    if( i != 0){
      // particles[0] 즉 (200, 0)에 있는 입자에 대해서는 아래의 일을 하지 않습니다. 왜냐하면, 이 입자 앞에는 그 어떤 입자도 없기 때문입니다. 
      // parcicles[0]는 배열 맨 처음의 요소라서, 자신 앞에 다른 요소를 가지고 있지 않아 연결 작업이 무의미 합니다~
      
      let a = particles[i];
      let b = particles[i - 1];
      let spring = new Spring(k, spacing, a, b);
      //요소 particles[i]는 자신 바로 앞에 있는 요소 particles[i-1]과 스프링으로 연결됩니다.~^^*
      
      springs.push(spring);
      //생성된 spring을 배열 spings[]에 저장합니다. 
      //배열 springs[]는 배열 particles[]보다 요소가 1개 적게 되겠네요? (1->0), (2->1), (3->2), (4->3) 총 4개의 spring이 생성되어 배열 springs[]에 저장됩니다~^^*
      
    }
  }
}  
  
  
function draw() {

  background(220);
  
  for( let s of springs){
    s.update();
    s.show();
  }
  //모든 스프링의 움직임을 보여주고
  
  for ( let p of particles){
    p.update();
    p.show();
  }
  //모든 스케이트 꿈나무들의 움직임을 보여줍니다.
  
  let tail = particles[particles.length - 1];
  //배열 맨마지막 요소를 변수 tail에 저장하겠습니다~

  if (mouseIsPressed) {
   tail.position.set(mouseX, mouseY);
   tail.velocity.set(0,0);
  }
  //마우스/손가락을 클릭/눌러서 스케이트 꿈나무 대열의 맨 마지막 스케이터를 움직여 보셔요~^^*
  //꿈나무 대열이 스슈슉 스슈슉 다 같이 나란히 따라 오나요~^^*
}

피겨 스케이트 계의 별이 될 꿈나무들을 육성하는 기쁨을 느껴보는 멋진 토요일 아침이 되시길 바래요~^^* 그대의 손끝을 따라 쪼로록 따라오며 열심히 훈련하는 꿈나무님들을 만나보러 가실까요~~^^*

아우~~~^^* 자애롭고 열정적인 코치님의 지도를 따라 끈기를 가지고 연습에 참여하는 우리 꿈나무님들을 보고 있으니, 이 아이스링크장은 춥지만 마음은 따뜻해 지는군요!!!

오늘도 저와 함께 코딩 공부 해주셔서 감사합니다~^^*

내일 우리 또 만나서 코딩 공부 함께 해요~~~^^*

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

댓글 남기기