Silverback9

#야생으로

Creative Coding 독학 제128일 2024년08월02일(금)

오늘도 많이 덥네요!! 네, 정말 8월 Down 날씨인데요!!! 핫Hot핫!!!

네~^^* 웃음 소리에도 더위의 텐션이 느껴지네요~^^* Hot핫Hot!!!

오늘은 아침 오후 저녁 볼 일이 있어서 Code 공부 업로드를 못하고 있어요~~^^;;

밤에~~ 하늘이 새까만 밤에~~ code 공부 업로드를 하도록 할게요~~^^*

밤이 찾아오길 기다리시는 동안~^^*, 자연과 인공과 역사의 조화 속에서 휴식하는 귀여운 K-생명체를 감상하시기 바래요~~^^*

네~~^^* 줌인 해볼까요~~^^*

멋스런 명당을 찾아 곤하게 주무시고 계신 K-고양이님~~^^*

금요일 저녁입니다~~^^* 휴식되는 저녁 보내시구요~~^^*

우리~~^^* 하늘이 새까만 한밤에 만나서 코딩 공부 함께 해요~~^^*

저녁에 할 일들을 잘 마치고 곧 돌아올게요~~^^*

금요일의 끝과 토요일의 시작 사이에 새까만 하늘의 밤이 누워 있어요~^^*

넵!! 지금부터 코드 공부를 시작해 보겠습니다~^^*

어제 그려보았던 그림대로 코드를 짜면 거의 다 완성된 것이나 다름 없을 것 같아요~~^^*

어제 그렸던 그림을 다시 한 번 살펴 보면서, 코드로 깔끔하게 입력해 보겠습니다~^^*

하나. class vehicle의 함수 constructor()를 다듬어 볼게요~^^*

 constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(1, 0);
    this.acc = createVector(0, 0);
    this.maxSpeed = 4;
    this.maxForce = 0.2;
    this.r = 16;
    
    this.wanderTheta = PI/3;
  }
  //최대 속도 4, 최대 힘 0.2로 설정하여, vehicle의 움직임 변화를 줄여보겠습니다. 
  //원 wander 내부의 회전각 크기를 PI/3 (60도)로 설정해 보겠습니다. 

둘. vehicle의 움직임 방향과 같고, 크기가 100인 벡터를 만들어 붉은 점 wanderPoint를 그려보겠습니다~^^*

    let wanderPoint = this.vel.copy();
    wanderPoint.setMag(100);
    wanderPoint.add(this.pos);
    fill(255, 0, 0);
    noStroke();
    circle(wanderPoint.x, wanderPoint.y, 16);

// vehicle의 velocity 방향의 연장선상에 있고, vehicle의 head에서 출발하여 크기가 100 인 벡터입니다~ 

셋. 붉은 점을 중심으로 radius 50의 원 wander를 그려보겠습니다.


    let wanderRadius = 50;
    noFill();
    stroke(255);
    circle(wanderPoint.x, wanderPoint.y, wanderRadius * 2);
    line(this.pos.x, this.pos.y, wanderPoint.x, wanderPoint.y);
// 원을 그리고, 붉은 점 wanderPoint와 vehicle 사이를 잇는 선도 그리겠습니다~

넷. class vehicle 회전각 wanderTheta와 vehicle의 운동속도 velocity의 회전각을 더한 값이 원 wander 내부의 회전각으로 작동할 때, 원 wander의 테두리에 생성되는 파란 점을 그리고, 이 점을 wanderPoint로 새롭게 정의해 보겠습니다~

    let theta = this.wanderTheta + this.vel.heading();

    let x = wanderRadius * cos(theta);
    let y = wanderRadius * sin(theta);
    wanderPoint.add(x, y);
    fill(0, 0, 255);
    noStroke();
    circle(wanderPoint.x, wanderPoint.y, 16);

    stroke(255);
    line(this.pos.x, this.pos.y, wanderPoint.x, wanderPoint.y);

// 새롭게 wanderPoint가 된 파란 점과 vehicle를 잇는 선도 그려보겠습니다~

다섯. vehicle이 파란 점 wanderPoint에 가장 빨리 다가가는 velocity를 계산하고, vehicle의 최대Force의 한계를 반영한 힘을 vehicle에게 적용해 보겠습니다~

    let steer = wanderPoint.sub(this.pos);
    steer.setMag(this.maxForce);
    this.applyForce(steer);

이제 복습 삼아 어제의 그림과 비교해 볼까요~^^*

이제 wanderTheta의 크기에 따라 vehicle이 배회하는 모습이 달라지는 것을 살펴 볼까요~^^* 클릭해 보셔요~~^^*

(1) 회전각이 0일 때!

(2) 회전각이 PI/2 (90도)일 때!

(3) 회전각이 PI/3 (60도)일 때!

이번에는~~^^* 배회하는 모습이 좀더 자연스러울 수 있도록~~^^* 회전각이 미세하게 무작위로 변화하도록 만들어 보겠습니다~~^^*

 let displaceRange = 0.3;
 this.wanderTheta += random(-displaceRange, displaceRange);
// 회전각이 +/- 0.3 범위 안에서 무작위로 변화하도록 만들어 보겠습니다~

(4) 회전각이 PI/3 (60도)이면 +/- 0.3 범위 안에서 무작위로 변화할 때!

네~!! 이제 (4)번의 전체 코드를 함께 살펴 볼까요~^^*

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

  </head>
  <body>
    <script src="vehicle.js"></script>
    <script src="sketch.js"></script>
  </body>
</html>
class Vehicle {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(1, 0);
    this.acc = createVector(0, 0);
    this.maxSpeed = 4;
    this.maxForce = 0.2;
    this.r = 16;
    
    this.wanderTheta = PI/3;
  }
  
  wander() {
    let wanderPoint = this.vel.copy();
    wanderPoint.setMag(100);
    wanderPoint.add(this.pos);
    fill(255, 0, 0);
    noStroke();
    circle(wanderPoint.x, wanderPoint.y, 16);

    let wanderRadius = 50;
    noFill();
    stroke(255);
    circle(wanderPoint.x, wanderPoint.y, wanderRadius * 2);
    line(this.pos.x, this.pos.y, wanderPoint.x, wanderPoint.y);

    let theta = this.wanderTheta + this.vel.heading();

    let x = wanderRadius * cos(theta);
    let y = wanderRadius * sin(theta);
    wanderPoint.add(x, y);
    fill(0, 0, 255);
    noStroke();
    circle(wanderPoint.x, wanderPoint.y, 16);

    stroke(255);
    line(this.pos.x, this.pos.y, wanderPoint.x, wanderPoint.y);

    let steer = wanderPoint.sub(this.pos);
    steer.setMag(this.maxForce);
    this.applyForce(steer);

    let displaceRange = 0.3;
    this.wanderTheta += random(-displaceRange, displaceRange);
  }

  applyForce(force) {
    this.acc.add(force);
  }

  update() {
    this.vel.add(this.acc);
    this.vel.limit(this.maxSpeed);
    this.pos.add(this.vel);
    this.acc.set(0, 0);
  }

  show() {
    stroke(255);
    strokeWeight(2);
    fill(255);
    push();
    translate(this.pos.x, this.pos.y);
    rotate(this.vel.heading());
    triangle(-this.r, -this.r / 2, -this.r, this.r / 2, this.r, 0);
    pop();
  }

  edges() {
    if (this.pos.x > width + this.r) {
      this.pos.x = -this.r;
    } else if (this.pos.x < -this.r) {
      this.pos.x = width + this.r;
    }
    if (this.pos.y > height + this.r) {
      this.pos.y = -this.r;
    } else if (this.pos.y < -this.r) {
      this.pos.y = height + this.r;
    }
  }
}
let vehicle;

function setup() {
  createCanvas(400, 400);
  vehicle = new Vehicle(100, 100);
}

function draw() {
  background(0);

  vehicle.wander();
  
  vehicle.update();
  vehicle.show();
  vehicle.edges();
}

마지막으로, 동영상 강의 내용도 복습으로 한 번 더 보셔도 좋을 듯 합니다~^^* 9:54까지 보시면 복습 끝~^^*

새까만 하늘의 밤이 토요일 쪽으로 서서히 몸을 돌리고 있는 지금까지~~^^* 저와 함께 코딩 공부 해주셔서 감사합니다~~^^*

노란 별빛들이 지켜주는 이 밤 편안히 주무시기 바래요~^^* 밤이 새벽으로 바뀌는 하늘 아래 시원한 해변을 여유롭게 배회하는 멋진 꿈도 꾸시는 여름 밤 보내시면 좋겠어요~~^^* Sweet Dreams~~^^*

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

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

댓글 남기기