Silverback9

#야생으로

Creative Coding 독학 제179일 2024년09월22일(일)

오늘은 물리 속성들 중 Constraint를 사용하여, 물체들 사이의 거리를 유지하는 코드를 공부해 보겠습니다~^^*

Constraint는 두 물체 사이의 거리를 일정하게 유지하는 속성인데요….공간에 물체로서 자리를 차지하지 않아요. 그저 두 물체 사이에 작용되는, 서로 일정한 거리를 유지하면서 서로 끌어당기는 어떤 힘이라고나 할까요?

자석의 다른 극끼리 끌어당기고 같은 극끼리 밀어내는, 물리적 공간을 차지하지 않는 어떤 힘을 느껴보신 적이 있으실 것 같아요? 그 두 가지 힘이 조합되어, 밀어내면서도 끌어당겨서, 두 물체가 일정한 거리를 유지하게 되는 경우가 이렇지 않을까? 생각해 보았어요.

const {
    Engine,
    World,
    Bodies,
    Composite,
    Constraint
} = Matter;

Constraint가 작용하는 두 물체는, 처음 물체는 BodyA 로 표기하고, 다음 물체는 BodyB 라고 표기를 하네요~^^*

두 물체 사이의 거리는 length 로 표기하고~, 두 물체가 이 거리를 유지하는 힘의 정도는 stiffness 로 표기하는 것 같아요~^^*

두 물체 사이의 거리를 측정하는 기준은, pointApointB 로 표기하는데요~ 물체 중심 (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를 점점 줄여가며 만나게 되는 예쁜 동그라미들~~^^*

이제 화면 양 끝에서 생성되었는데, constraint 에 의해 서로의 거리가 20 pixel 로 유지되어, 화면 가운데에서 나란히 내려오는, 두 개의 동그라미를 보러 가실까요~~^^*

Option의 Length를 다양하게 조정하여 플레이 해 보시면 더욱 재미있겠지요~^^*

두 물체 사이의 거리를 일정하게 유지하는 힘! Constraint 속성을 오늘 저와 함께 공부해 주셔서 감사합니다~^^*

우리 내일은 편안하게 음악 같이 듣구요~~^^*

화요일엔, 이 Constraint를 이용해서 재미난 사물현상을 또 만들어 보면 좋겠어요~~^^*

동그라미들이 완전히 자유롭게 움직이지 않고 어떤 힘에 의해 서로의 거리를 유지하여 전체적으로 어떤 재미있는 모습을 동그라미들이 함께 만들어 낼 수 있을 것 같아요~^^*

우리의 사고 파편들 사이에도 이런 Constraint가 작용하면, 창의적인 어떤 아이디어가 구성될 수 있을까요?

오늘도 즐거운 아침! 즐거운 하루! 보내시구요!

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

댓글 남기기