Silverback9

#야생으로

Creative Coding 독학 제147일 2024년08월21일(수)

오늘은 본격적으로 Path Following 프로그램의 구성 요소들을 준비해 볼까요~~^^* YEAH~~^^*

어제 우리가 정리해 본 알고리즘의 복습을 겸해서, 아래 동영상 강의를 처음부터 8:42까지 보시면 더 좋을 것 같아요~~^^*

먼저, 길을 닦아 볼까요~^^*

길의 특성을 가진 Class Path를 정의해 봅시다~

하나. 클래스 Path의 구성요소를 정의하는 함수 constructor()는~~^^* 

   (i) 시작점 위치좌표와 끝점 위치좌표를 받아서 벡터 start와 벡터 end를 생성합니다~~^^*

   (ii) 아참!!! 길의 폭을 설정하는 것이 중요하겠지요~! 길의 반지름 변수 radius도 정의해 볼게요~

둘. 길을 화면에 보여주는 함수 show()는~~^^* 

   (i) 중앙선을 표현하기 위해서 벡터 start의 위치좌표와 벡터 end의 위치좌표를 잇는 선을 만들겠습니다~~^^*

  (ii) radius 폭만큼 양쪽으로 두꺼운 회색선으로 벡터 start와 벡터 end의 위치좌표를 이어서 도로의 너비를 표현해 보겠습니다~^^*
class Path{
  constructor(x1, y1, x2, y2) {
    this.start = createVector(x1, y1);
    this.end = createVector(x2, y2);
    this.radius = 20;
  }
  show() {
    stroke(255);
    strokeWeight(2);
    line(this.start.x, this.start.y, this.start.y, this.end.y);

    stroke(200);
    strokeWeight(2*this.radius);
    line(this.start.x, this.start.y, this.start.y, this.end.y);
  }
}

네~ 길이 완공되었으니 vehicle이 쌩쌩 도로 위를 달리면 되겠네요~

아참!! 그전에!!! vehicle이 도로에 드리우는 Scalar Projection의 끝점을 계산하는 함수를 미리 준비해 두도록 할게요~^^*

차양막 tarp가 바닥 ground에 내리우던 그림자 shade의 끝점 shadeEndPoint를 계산하던 함수를 가져와서, 변수 이름들만 간단하게 수정해 놓겠습니다~^^*

function findScalarProjection(pos, a, b) {
let v1 = p5.Vector.sub(a, pos);
let v2 = p5.Vector.sub(b, pos);
v2.normalize();
let sp = v1.dot(v2);
v2.mut(sp);
v2.add(pos);
return v2;
}

길이 잘 닦아졌으니, 이제 이 길을 따라갈 vehicle을 준비해 볼까요~~^^*

우리가 이전 프로그램에서 자주 쓰던 Class Vehicle에 path following 기능을 추가하여 사용하면 어떨까요~~^^*

함수 follow()를 만들어 Class Vehicle에 추가하겠습니다~

먼저, vehicle의 미래 위치를 파악해야 할 것 같아요!!

현재 vehicle의 velocity에 50을 곱하겠습니다. 그리고 현재의 위치좌표에 이 velocity를 더하면, 50 frame 후의 vehicle의 위치좌표가 나올 것 같아요. 이 미래의 vehicle의 위치를 붉은 점으로 표현해 보겠습니다~~^^*

이제는 미래의 vehicle이 도로 위에 드리우는 Scalar Projection의 끝점을 찾아서 초록색 점으로 표현해 보겠습니다.

이 Scalar Projection 끝부분을 target으로 vehicle이 몸을 돌리게 되니까, 이름을 target으로 불러보는 것도 좋겠죠~~^^*

도로의 시작부분과 미래의 vehicle 사이에 발생하는 벡터 future가 도로의 시작부분과 도로의 끝부분 사이에 발생하는 벡터 end 위에 드리우는 Scalar Projection의 끝부분 target을 표현하는 것이기도 하네요~

follow(path) {
let future = this.vel.copy();
future.mult(50);
future.add(this.pos);
fill(255, 0, 0);
nostroke();
circle(future.x, future.y, 16);

let target = findScalarProjection(path.start, future, path.end);
fill(0, 255, 0);
nostroke();
circle(target.x, target.y, 16);
}

현재까지 준비된 재료를 사용할 수 있는 메인 함수도 준비해 두겠습니다~~

let vehicle;
let path;

function setup(){
createCanvas(400, 400);
vehicle = new Vehicle(100, 100);
vehicle.vel.x = 2;
path = new Path(0, 200, 400, 200);
}

function draw(){
background(0);
vehicle.edges();
vehicle.update();
vehicle.show();

path.show();
}

네~~^^* 오늘은 Path Following 프로그램을 위한 준비 재료들을 몇 가지 만들어 보았습니다~~^^*

네^^* 요리의 시작은~~~재료준비~~~~^^*

내일은 거리와 폭의 관계성에 따라 몸을 돌리는 행동도 함수 follow()에 추가해 보도록 하겠습니다~~

오늘 저와 함께 차근차근 코드 재료 손질을 함께 해 주셔서 감사합니다~^^**

내일 우리 또 만나서, 재료를 좀더 정교하게 다듬어 멋진 요리를 완성해 볼까요~~^^*

오늘 아침도 멋진 아침! 오늘 하루도 멋진 하루! 보내셔요~~^^*

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

댓글 남기기