오늘은 본격적으로 코딩 작업을 하는 날이예요~^^*
지난 주 오늘은 아주 반가운 햇살이 아침을 채워 주었는데요~^^*
이번 주 오늘은 차분한 빗살이 유리창을 쓰다듬어 주고 있어요~^^*
창문이 하늘을 향해 고개를 젖히고 있어서요~^^* 뺨에 닿는 빗살의 보드란 손길을 창문이 두 눈을 감고 가만히 편안히 느끼고 있어요~^^*

편안하고 즐거운 아침 시작하시구요~^^* 저는 오후에 코딩 공부해서 다시 찾아 올게요~^^*
바람은 잔잔해서 내리는 비를 상쾌하게 만들어 주는 오늘의 오후입니다~^^*
어제 본 동영상 강의를 다시 한 번 보면서 본격적인 코딩 작업을 해 볼게요~^^*
힘의 한계와 속력의 한계를 지닌 생명체가 환경의 변화에 반응하며 자신의 행동 계획을 수립하고 수정하고 실행해 나가는 우리의 현실 세계를 코드에 담는 오늘이네요~^^*
힘의 한계와 속력의 한계를 지닌 채 자신의 최선을 다하는 연약하고도 멋진 우리 Vehicle~^^*
Vehicle이 차근차근 생각하고 멋지게 실행해 내는 과정을 단계별로 살펴 볼까요~^^*
(1) 자신과 target 사이의 거리를 최대한 빨리 0으로 줄이는 desired_vector를 계산하고
let force = p5.Vector.sub(target, this.pos);
(2) 자신이 낼 수 있는 속력의 한계를 desired_vector에 반영하고
force.setMag(this.maxSpeed);
(3) 자신의 현재 움직임에 영향을 주는 속도 current_vel를 뺄셈하고
force.sub(this.vel);
(4) 자신이 낼 수 있는 힘의 한계를 반영하고
force.limit(this.maxForce);
(5) 현재 자신에 의해 작용되는 힘에 이 steering 힘을 더하고~^^*
this.applyForce(force);
(6) 이 힘의 영향으로 새롭게 변화된 자신의 현재 속도에 자신이 낼 수 있는 속력의 한계를 반영합니다~^^*
this.vel.limit(this.maxSpeed);
(7) Vehicle이 자신이 움직이는 방향으로 자신의 얼굴도 향하도록 하여 자연스러운 움직임을 보여주겠습니다~^^*
하나. Vehicle의 위치(x, y)를 중심으로 하는 좌표체계로 변환합니다.
둘. Vehicle의 움직임 방향으로 좌표축을 회전합니다.
셋. Vehicle을 삼각형 형태로 그립니다.
넷. push()-pop() 구조를 사용하여, 위 세 단계의 일을 실행한 후 실행문 데이터를 삭제를 함으로써, 좌표체계 변환과 좌표축 회전이 Vehicle에게만 독립적으로 적용되도록 합니다.
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();
Autonomous Agent의 Steering Behaviour의 핵심 코드를 살펴 보았으니, 이제 전체 코드를 함께 살펴 볼까요~^^*
<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(0, 0);
this.acc = createVector(0, 0);
this.maxSpeed = 4;
this.maxForce = 0.25;
this.r = 16;
}
seek(target) {
let force = p5.Vector.sub(target, this.pos);
force.setMag(this.maxSpeed);
force.sub(this.vel);
force.limit(this.maxForce);
this.applyForce(force);
}
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;
let target;
function setup() {
createCanvas(400, 400);
vehicle = new Vehicle(100, 100);
}
function draw() {
background(0);
fill(255, 0, 0);
noStroke();
target = createVector(mouseX, mouseY);
circle(target.x, target.y, 32);
vehicle.seek(target);
vehicle.update();
vehicle.show();
}
//마우스/손가락을 움직여 target의 위치를 변화시켜 보셔요~^^*
Target을 찾을 때까지 Vehicle은 계속 달립니다~^^*
Target이 뒤돌아보면 항상 Vehicle이 거기 서있을테요~!
“전세계에서 가장 성공한 Seeker의 노래”처럼 우리 Vehicle도 임무를 성공하였습니다~^^*
몇 달 전에도 멋진 공연을 해내신 Sting처럼, 우리도 코딩 공부 꾸준히 해볼까요~~^^*
오늘도 저와 함께 코딩공부 해주셔서 감사합니다~^^*
내일도 우리 새로운 도전을 향해 함께 나아가면 좋겠어요~~^^*
네!! 꿈은 이루어 집니다~!!!
댓글 남기기