오늘은 물리 속성들 중 Constraint를 사용하여, 물체들 사이의 거리를 유지하는 코드를 공부해 보겠습니다~^^*
Constraint는 두 물체 사이의 거리를 일정하게 유지하는 속성인데요….공간에 물체로서 자리를 차지하지 않아요. 그저 두 물체 사이에 작용되는, 서로 일정한 거리를 유지하면서 서로 끌어당기는 어떤 힘이라고나 할까요?
자석의 다른 극끼리 끌어당기고 같은 극끼리 밀어내는, 물리적 공간을 차지하지 않는 어떤 힘을 느껴보신 적이 있으실 것 같아요? 그 두 가지 힘이 조합되어, 밀어내면서도 끌어당겨서, 두 물체가 일정한 거리를 유지하게 되는 경우가 이렇지 않을까? 생각해 보았어요.
const {
Engine,
World,
Bodies,
Composite,
Constraint
} = Matter;
Constraint가 작용하는 두 물체는, 처음 물체는 BodyA 로 표기하고, 다음 물체는 BodyB 라고 표기를 하네요~^^*
두 물체 사이의 거리는 length 로 표기하고~, 두 물체가 이 거리를 유지하는 힘의 정도는 stiffness 로 표기하는 것 같아요~^^*
두 물체 사이의 거리를 측정하는 기준은, pointA 와 pointB 로 표기하는데요~ 물체 중심 (matter.js의 물체 위치 좌표)가 Default 값으로 설정되어 있어요.
우리는 물체 중심을 거리 측정 기준으로 그대로 사용해 볼까요? 그러면, Default 값을 그대로 쓰게 되는 것이니까, Option에 넣지 않아도 될 것 같습니다~
자, 그럼 우리, 동그라미 P1, P2 두 개를 화면 양 끝 제일 위에 생성하고~, stiffness 거리 유지 강도 0.4로 서로의 거리 length 를 20 으로 유지하도록~ options을 설정하는 코드를 정리해 볼까요~^^*
let particles = [];
let p1 = new Particle(0, 0, 10);
let p2 = new Particle(400, 0, 10);
particles.push(p1);
particles.push(p2);
let options = {
bodyA: p1.body,
bodyB: p2.body,
length: 20,
stiffness: 0.4
}
이 옵션에 따라 Constraint 물체 사이 거리 유지 힘을 생성하여, Engine.world에 구성요소로 더해 봅시다~^^*
let engine;
let world;
engine = Engine.create();
world = engine.world;
let constraint = Constraint.create(options);
World.add(world, constraint);
Constraint를 생성하는 핵심 코드 준비가 끝났네요~~!! YEAH~~!!
그럼 이제 전체 코드를 저와 함께 살펴 보러 가시죠!!! 출발~~!!!
<!DOCTYPE html>
<html lang="en">
<head>
https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js
https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/addons/p5.sound.min.js
https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<main>
</main>
http://sketch.js
http://circle.js
http://boundary.js
</body>
</html>
class Boundary {
constructor(x, y, w, h, a) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
let options = {
friction: 0,
restitution: 0.6,
angle: a,
isStatic: true
}
this.body = Bodies.rectangle(this.x, this.y, this.w, this.h, options);
Composite.add(world, this.body);
}
show() {
let pos = this.body.position;
let angle = this.body.angle;
push();
translate(pos.x, pos.y);
rotate(angle);
rectMode(CENTER);
fill(0);
rect(0, 0, this.w, this.h);
pop();
}
}
class Particle{
constructor(x, y, r, fixed) {
this.x = x;
this.y = y;
this.r = r;
let options = {
friction: 0,
restitution: 0.95,
isStatic: fixed
}
this.body = Bodies.circle(this.x, this.y, this.r, options);
Composite.add(world, this.body);
}
show() {
let pos = this.body.position;
let angle = this.body.angle;
push();
translate(pos.x, pos.y);
rotate(angle);
rectMode(CENTER);
strokeWeight(1);
stroke(255)
fill(127);
ellipse(0, 0, this.r*2);
pop();
}
}
const {
Engine,
World,
Bodies,
Composite,
Constraint
} = Matter;
let engine;
let world;
let particles = [];
let boundaries = [];
function setup() {
createCanvas(400, 400);
engine = Engine.create();
world = engine.world;
let p1 = new Particle(0, 0, 10);
let p2 = new Particle(400, 0, 10);
//p1과 p2가 화면 양 쪽 끝 제일 위에서 생성이 되어요~^^*
particles.push(p1);
particles.push(p2);
let options = {
bodyA: p.body,
bodyB: prev.body,
length: 20,
//두 물체 사이 거리를 20 pixel로 잡으니~^^*
stiffness: 0.4
}
let constraint = Constraint.create(options);
World.add(world, constraint);
boundaries.push(new Boundary(width / 2, 400, width, 20, 0));
//화면 바닥에 선반을 평평하게 놓아 볼게요~
//동그라미가 닿으면 통통 튈 것 같아요~^^*
}
function draw() {
background(51);
Engine.update(engine);
for (let i = 0; i < boundaries.length; i++) {
boundaries[i].show();
}
for (i = 0; i < particles.length; i++) {
particles[i].show();
}
// 어머 두 물체가 화면 가운데, 20 pixel 거리를 유지하며 내려오게 될까요~^^*?
}
서로의 편안한 거리를 유지하며 유연한 평행선을 만들어 가는 예쁜 동그라미들~~^^*
Constraint의 length를 점점 줄여가며 만나게 되는 예쁜 동그라미들~~^^*
Option의 Length를 다양하게 조정하여 플레이 해 보시면 더욱 재미있겠지요~^^*
두 물체 사이의 거리를 일정하게 유지하는 힘! Constraint 속성을 오늘 저와 함께 공부해 주셔서 감사합니다~^^*
우리 내일은 편안하게 음악 같이 듣구요~~^^*
화요일엔, 이 Constraint를 이용해서 재미난 사물현상을 또 만들어 보면 좋겠어요~~^^*
동그라미들이 완전히 자유롭게 움직이지 않고 어떤 힘에 의해 서로의 거리를 유지하여 전체적으로 어떤 재미있는 모습을 동그라미들이 함께 만들어 낼 수 있을 것 같아요~^^*
우리의 사고 파편들 사이에도 이런 Constraint가 작용하면, 창의적인 어떤 아이디어가 구성될 수 있을까요?
오늘도 즐거운 아침! 즐거운 하루! 보내시구요!
네~^^* 꿈은 이루어 집니다~^^*!!!
댓글 남기기