추석연휴가 시작되었습니다~~^^*
이동의 피곤함을 충분히 가셔내고 천천히 앉은 책상 맡입니다~^^* 귿모닝~~^^*
명절을 맞으면, 그 날을 기점으로 한 4 계절이 마음 속에서 한 바퀴 도는 것 같아요.
2023 가을 – 2024 겨울 – 2024 봄 – 2024 여름
지난 365일을 천천히 되감으며 사계절를 거꾸로 걸어가는 연휴의 아침의 여유~^^*
이 여유가 4 계절은 왜 생기는 것일까? 새삼 궁금해 지도록 만드네요~^^*
사계절은 우리에게 서로 다른 감성을 선물하고~^^*
사계의 만만치않음을 깊이 있게 느끼게 하고~^^*
또다른 4계절이 시작됨을 마음 준비한 우리는, 옷장 속으로 들어가 가을의 문을 엽니다.
이제 우리가 들어서고 있는 가을 세계를 찬찬히 눈으로 만지며, 연휴의 아침을 누려볼까요~^^*
저는 그 동안 오늘의 코드 공부를 하고 다시 돌아올게요~^^* 푹 쉬고 계셔요~~^^*
우리 곧 또 다시 만나요~~^^*
네~^^* 돌아왔습니다~~^^*
편안한 아침 보내셨나요~~^^*
연의 실을 그리는 프로그램 기억하고 계시나요^^*
우리는 이제 p5.js the nature of code 강의 시리즈의 부록 프로그램까지 공부를 다 마쳤어요~^^*
그래서, 오늘은 연의 실 프로그램을 마무리 해 보면 어떨까요~^^*
p5.js 공부 포럼에 이 문제를 질문했었는데요~^^* 친절한 답변이 왔었거든요~^^*
// Count positions
let total = 0;
for (let path of this.paths) {
total += path.length;
}
if (total > 100) {
this.paths[0].shift();
if (this.paths[0].length === 0) {
this.paths.shift();
}
}
First, the question "When does the length of an item of an array become zero". On line 123 there's a this.paths[0].shift(). This removes the first element from the paths[0] array. This is done so that the line doesn't grow forever.
Next, if the paths[0] array is empty (.length === 0), remove it from the array paths. This is a simple optimization. Technically you can leave the empty array there, but it'll cause the sketch to slowdown eventually - JS will still have to loop over the array, even if just to skip it.
(1) 연의 실 배열의 요소의 총합을 100 이하로 유지하기 위해, 총합이 100을 넘어서면, 연의 실 배열의 첫번째 구성요소를 제거를 하고 : 구성 요소 제거
(2) 연의 실 배열이 비어있을 경우에는, 이 연의 실 배열을 전체 연의 실 타래 배열에서 제거한다: 배열 제거
** 작업 지시문 목적: 프로그램의 성능 최적화: 비어있는 배열을 괜히 점검하느라 시간을 소비하지 말자~
그럼, 연의 실 프로그램을 오래간만에 대하는 것이니, 기억을 되살릴 겸 복습 삼아 전체 코드를 저랑 함께 보실까요~^^*
<!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;
this.currentPath = [];
this.paths = [this.currentPath];
//캔버스 안에서 활동할 동안의 vehicle의 위치좌표를 모으는 배열this.currentPath
//배열 this.currentPath들을 모으는 배열 this.paths
}
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);
this.currentPath.push(this.pos.copy());
//vehicle의 위치좌표를 수집합니다.
// 꼬리 길이를 100로 제한하겠습니다.
let total = 0;
for (let path of this.paths) {
total += path.length;
}
if (total > 100) {
this.paths[0].shift();
//꼬리가 100보다 길어지면
//배열의 첫 번째 구성요소를 제거합니다.
if (this.paths[0].length === 0) {
this.paths.shift();
//배열이 비어있으면, 전체 배열에서 제거합니다.
}
}
}
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();
for (let path of this.paths) {
beginShape();
noFill();
for ( let v of path) {
vertex(v.x, v.y);
}
endShape();
}
//화면 안 움직임만을 모은 path들이 점들을 연결합니다.
}
edges() {
let hitEdge = false;
if (this.pos.x > width + this.r) {
this.pos.x = -this.r;
hitEdge = true;
} else if (this.pos.x < -this.r) {
this.pos.x = width + this.r;
hitEdge = true;
}
if (this.pos.y > height + this.r) {
this.pos.y = -this.r;
hitEdge = true;
} else if (this.pos.y < -this.r) {
this.pos.y = height + this.r;
hitEdge = true;
}
//vehicle이 화면 밖을 나가면 좌<->우 상<->하 이동하여 화면 안에 다시 들어올 준비를 합니다.
//화면 밖으로 나간다는 token hitEdge를 활성화시킵니다.
if(hitEdge) {
this.currentPath = [];
this.paths.push(this.currentPath);
}
//vehicle이 화면 밖으로 나가면, 화면 안 움직임을 기록하는 currentPath를 새로 만듭니다.
//currentPath들을 모으는 배열 path의 끝에 넣습니다.
}
}
let vehicle;
function setup() {
createCanvas(400, 400);
vehicle = new Vehicle(100, 100);
}
function draw() {
background(0);
vehicle.wander();
vehicle.update();
vehicle.show();
vehicle.edges();
}
네~~^^*
오늘로서, p5.js the nature of code 강의 시리즈는 마무리가 되었습니다~^^*
그동안 저와 함께 코딩 공부를 해주셔서 정말 감사드려요~~^^*
앞으로의 4계절 동안, 우리 또 매일 아침 코딩 공부 함께 하면 좋겠어요~~^^*
다양한 주제와 새로운 도전들이 우리를 기다리고 있어요~^^*
옷장을 덮고 있는 흰 천을 젖힐 준비가 되셨나요~~^^*
네~^^* 그럼 우리 내일 또 새로운 세계에서 다시 만나요~~^^*
오늘도 즐거운 오후! 편안한 저녁과 깊은 밤! 보내셔요!
네~~!!! 꿈은 이루어 집니다~~!!!
댓글 남기기