66651
๐Ÿ‘€
66651
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (57)
    • note (28)
    • log (13)
    • error (9)
    • etc (7)

๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

  • ํ™ˆ
  • ํƒœ๊ทธ
  • ๋ฐฉ๋ช…๋ก

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
66651

๐Ÿ‘€

[JS] ํž˜ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ 1 | ์นธ ์•„์นด๋ฐ๋ฏธ
note

[JS] ํž˜ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ 1 | ์นธ ์•„์นด๋ฐ๋ฏธ

https://ko.khanacademy.org/computing/computer-programming/programming-natural-simulations/programming-forces/a/newtons-laws-of-motion

 

 

๋‰ดํ„ด์˜ ์šด๋™ ๋ฒ•์น™

 

๋ฒกํ„ฐ(vector)์ฒ˜๋Ÿผ, ํž˜(force)์€ ๋‹ค์–‘ํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํž˜์€ ์–ด๋–ค ๊ฐ•๋ ฅํ•œ ๋ฌผ๋ฆฌ๋ ฅ, ์ด๋ฅผํ…Œ๋ฉด, ๋ฐ”์œ„๋ฅผ ํฐ ํž˜์œผ๋กœ ๋ฏธ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š” ๊ฐœ๋…์ด ๋  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋‹ค๋ฃฐ ํž˜ ์˜ ์ •์˜๋Š” ๋ฌผ๋ฆฌํ•™์—์„œ ๋ฐฐ์šฐ๋Š” ํž˜์ด๊ณ , ์•„์ด์ž‘ ๋‰ดํ„ด(Isaac Newton)์˜ ์šด๋™์˜ ๋ฒ•์น™์—์„œ ๋น„๋กฏ๋œ ๊ฐœ๋…์ด๋‹ค.

 

ํž˜์€ ์งˆ๋Ÿ‰์„ ์ง€๋‹Œ ๋ฌผ์ฒด๋ฅผ ๊ฐ€์†ํ•˜๋Š” ๋ฒกํ„ฐ๋‹ค.

 

 

๋‰ดํ„ด์˜ ์ œ1๋ฒ•์น™

 

๋‰ดํ„ด์˜ ์ œ1๋ฒ•์น™์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•œ๋‹ค.

์›€์ง์ด์ง€ ์•Š๋Š” ๋ฌผ์ฒด๋Š” ๊ณ„์† ์›€์ง์ด์ง€ ์•Š์œผ๋ ค ํ•˜๊ณ  ์›€์ง์ด๋Š” ๋ฌผ์ฒด๋Š” ๋ถˆ๊ท ํ˜•๋ ฅ์ด ๊ฐ€ํ•ด์ง€์ง€ ์•Š๋Š” ํ•œ ์ผ์ •ํ•œ ์†๋„์™€ ๋ฐฉํ–ฅ์œผ๋กœ ๊ณ„์† ์›€์ง์ด๋ ค ํ•œ๋‹ค.

 

์• ์ดˆ์— ํž˜์ด ์•„์˜ˆ ์—†์œผ๋ฉด ๋ฌผ์ฒด๊ฐ€ ๊ณ„์† ์›€์ง์ด๊ฒŒ ํ•˜๋Š” ๋ฐ ์–ด๋– ํ•œ ํž˜๋„ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค. ์ง€๊ตฌ ๋Œ€๊ธฐ๊ถŒ์— ๋˜์ ธ์ง„ (๊ณต๊ณผ ๊ฐ™์€) ๋ฌผ์ฒด๋Š” ๊ณต๊ธฐ ์ €ํ•ญ(ํž˜) ๋•Œ๋ฌธ์— ์ ์ฐจ ๋А๋ ค์ง„๋‹ค.

 

ํž˜์ด ์—†๊ฑฐ๋‚˜ ๋ฌผ์ฒด์— ๊ฐ€ํ•ด์ง€๋Š” ํž˜์ด ์„œ๋กœ ์ƒ์‡„๋˜๋ฉด ์ฆ‰, ์•Œ์งœ ํž˜์ด ๊ฒฐ๊ตญ 0์ด ๋˜๋ฉด ๋ฌผ์ฒด์˜ ์†๋„๋Š” ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€๋œ๋‹ค. ์ด๊ฒƒ์„ ํ‰ํ˜•(equilibrium)์ด๋ผ ํ•œ๋‹ค. ์ผ๋‹จ ๊ณต๊ธฐ ์ €ํ•ญ๋ ฅ์ด ์ค‘๋ ฅ๊ณผ ๊ฐ™์•„์ง€๋ฉด ๋–จ์–ด์ง€๋Š” ๊ณต์€ (์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€๋˜๋Š”) ์ข…๋‹จ ์†๋„์— ๋„๋‹ฌํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

 

ProcessingJS ์„ธ๊ณ„์—์„œ ๋‰ดํ„ด์˜ ์ œ1๋ฒ•์น™์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค์‹œ ๊ธฐ์ˆ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ์ฒด์˜PVector ์†๋„๋Š” ํ‰ํ˜•์˜ ์ƒํƒœ์— ์žˆ๋Š” ๊ฒฝ์šฐ ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€๋œ๋‹ค.

 

 

๋‰ดํ„ด์˜ ์ œ3๋ฒ•์น™

 

์ด ๋ฒ•์น™์€ ์ข…์ข… ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ธฐ์ˆ ๋œ๋‹ค.

๋ชจ๋“  ์ž‘์šฉ์€ ๋ฐ˜๋Œ€๋ฐฉํ–ฅ์œผ๋กœ ๋˜‘๊ฐ™์€ ํž˜์„ ๊ฐ€์ง€๋Š” ๋ฐ˜์ž‘์šฉ์ด ์žˆ๋‹ค.

 

๋ฒฝ์„ ๋ฏผ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด์ž. ๋ฒฝ์€ ์ ๊ทน์ ์œผ๋กœ ์šฐ๋ฆฌ๋ฅผ ๋ฐ˜๋Œ€๋กœ ๋ฐ€์ง€๋Š” ์•Š๋Š”๋‹ค. ๋ฒฝ์€ ์šฐ๋ฆฌ๋ฅผ ๋ฐ€๋งŒ ํ•œ ๊ทผ์›์ด ๋˜๋Š” ํž˜์„ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ์˜ ๋ฏธ๋Š” ํž˜์—๋Š” “์ž‘์šฉ/๋ฐ˜์ž‘์šฉ์ด ์Œ”์ด ๋˜๋Š” ๋‘ ๊ฐœ์˜ ํž˜์ด ํฌํ•จ๋œ๋‹ค.

 

ํž˜์€ ํ•ญ์ƒ ์Œ์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค. ๋‘ ํž˜์€ ์„ธ๊ธฐ๊ฐ€ ๊ฐ™์ง€๋งŒ ๋ฐฉํ–ฅ์€ ๋ฐ˜๋Œ€๋‹ค.

 

๋‰ดํ„ด์˜ ์ œ3 ๋ฒ•์น™์„ ProcessingJS์— ๋งž๊ฒŒ ๋‹ค์‹œ ๊ธฐ์ˆ ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๋ฌผ์ฒด B์— ๋Œ€ํ•œ ๋ฌผ์ฒด A์˜ ํž˜์ธ PVector f ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ ๋ฌผ์ฒด B๊ฐ€ ๋ฌผ์ฒด A์— ๊ฐ€ํ•˜๋Š” ํž˜์ธ PVector.mult(f,-1);๋„ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

๋‚˜์ค‘์— ProcessingJS ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์„ธ๊ณ„์—์„œ ํ•ญ์ƒ ์œ„ ๋ฒ•์น™์„ ๋”ฐ๋ฅผ ํ•„์š”๋Š” ์—†๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ์ •๋ฐ€ํ•˜๊ฒŒ ๋ชจ๋“  ๊ฒƒ์„ ์™„๋ฒฝํžˆ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์„ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‹จ์ง€ ์ž์—ฐ๊ณ„์˜ ๋ฌผ๋ฆฌ ํ˜„์ƒ์—์„œ ์˜๊ฐ์„ ์–ป๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ธฐ์–ตํ•˜์ž.

 

 

 

๋‰ดํ„ด์˜ ์ œ2๋ฒ•์น™

 

์ „ํ†ต์ ์œผ๋กœ ์ด ๊ทœ์น™์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•œ๋‹ค.

ํž˜์€ ์งˆ๋Ÿ‰ ๊ณฑํ•˜๊ธฐ ๊ฐ€์†๋„์ด๋‹ค. 

 

 

 

์ฆ‰ ๊ฐ€์†๋„๋Š” ํž˜๊ณผ ๋น„๋ก€ํ•˜๊ณ  ์งˆ๋Ÿ‰์— ๋ฐ˜๋น„๋ก€ํ•œ๋‹ค.

 

์—ฌ๊ธฐ์„œ ๋ฌผ์ฒด์˜ ์งˆ๋Ÿ‰์€ ๋ฌผ์ฒด์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๋ฌผ์งˆ์˜ ์–‘์ด๋‹ค. ๋ฌด๊ฒŒ๋Š” ๋ฌผ์ฒด์— ์ž‘์šฉํ•˜๋Š” ์ค‘๋ ฅ์˜ ํž˜์„ ๋งํ•œ๋‹ค.
๋‰ดํ„ด์˜ ์ œ 2 ๋ฒ•์น™์— ๋”ฐ๋ผ ์งˆ๋Ÿ‰ ๊ณฑํ•˜๊ธฐ ์ค‘๋ ฅ ๊ฐ€์†๋„ (w = m * g)๋ฅผ ํ†ตํ•ด ๋ฌด๊ฒŒ๋ฅผ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐ€๋„๋Š” ์งˆ๋Ÿ‰์„ ๋‹จ์œ„ ๋ถ€ํ”ผ๋กœ ๋‚˜๋ˆˆ ๊ฐ’์œผ๋กœ ์ •์˜ํ•œ๋‹ค.

 

์ง€๊ตฌ์—์„œ ์งˆ๋Ÿ‰์ด 1 kg์ธ ๋ฌผ์ฒด๋Š” ๋‹ฌ์—์„œ๋„ ์งˆ๋Ÿ‰์ด 1 kg๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฌด๊ฒŒ๋Š” 1/6๋กœ ์ค„์–ด๋“ ๋‹ค.

 

์ด์ œ ProcessingJS์˜ ์„ธ๊ณ„์—์„œ ์งˆ๋Ÿ‰์€ ๋ฌด์—‡์ผ๊นŒ? ๊ฐ„๋‹จํžˆ ํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์ƒ์˜ ํ”ฝ์…€ ์„ธ๊ณ„์—์„œ ๋ชจ๋“  ๋ฌผ์ฒด๋“ค์˜ ์งˆ๋Ÿ‰์€ 1์ด๋ผ๊ณ  ํ•˜์ž. F/1 = F์ด๋‹ค. ๋”ฐ๋ผ์„œ, ๋‹ค์Œ์ด ์„ฑ๋ฆฝํ•œ๋‹ค.

๋ฌผ์ฒด์˜ ๊ฐ€์†๋„๋Š” ํž˜๊ณผ ๊ฐ™๋‹ค.

 

Mover ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฐฐ์› ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ํ˜„์žฌ ์œ„์น˜, ์†๋„, ๊ฐ€์†๋„๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž. ์ง€๊ธˆ ๋ชฉํ‘œ๋Š” ์ด ๊ฐ์ฒด์— ํž˜์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

mover.applyForce(wind);

// or

mover.applyForce(gravity);

 

์ด๋•Œ, ๋ฐ”๋žŒ๊ณผ ์ค‘๋ ฅ์€ PVector์ด๋‹ค. ๋‰ดํ„ด์˜ ์ œ2๋ฒ•์น™์— ๋”ฐ๋ผ ์ด ํ•จ์ˆ˜๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

Mover.prototype.applyForce = function(force) {
    this.acceleration = force;
};

 

 

 

ํž˜์˜ ์ถ•์ 

 

applyForce()๋Š” ๋‰ดํ„ด์˜ ์ œ2 ๋ฒ•์น™์„ ์ •์˜ ๊ทธ๋Œ€๋กœ ํ•ด์„ํ•œ ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์—๋Š” ๊ฝค ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ์ง€๊ธˆ ์ด๋ฃจ๊ณ ์ž ํ•˜๋Š” ๋ชฉํ‘œ๋Š” ํ™”๋ฉด์ƒ์—์„œ ๋ฐ”๋žŒ๊ณผ ์ค‘๋ ฅ์— ์˜ํ•ด ์›€์ง์ด๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

mover.applyForce(wind);
mover.applyForce(gravity);

 

์œ„์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•œ๋‹ค๋ฉด Mover ๊ฐ์ฒด์˜ ๊ฐ€์†๋„๋Š” ์ค‘๋ ฅ PVector๋กœ ์„ค์ •๋œ๋‹ค. ํ•œ ๋ฒˆ ์ด์ƒ applyForce()์„ ํ˜ธ์ถœํ•˜๋ฉด ์ด์ „ ํ˜ธ์ถœ์„ ๋ฌด์‹œํ•˜๊ณ  ๋ฎ์–ด์“ฐ๊ฒŒ ๋œ๋‹ค. ํ•˜๋‚˜ ์ด์ƒ์˜ ํž˜์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ๊นŒ?

 

๋‰ดํ„ด์˜ ์ œ2 ๋ฒ•์น™์„ ์ข€ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

์•Œ์งœ ํž˜์€ ์งˆ๋Ÿ‰ ๊ณฑํ•˜๊ธฐ ๊ฐ€์†๋„์™€ ๊ฐ™๋‹ค.

 

์ด๋Š” ๊ฐ€์†๋„๊ฐ€ ํž˜์˜ ์ด๋Ÿ‰ ์„ ์งˆ๋Ÿ‰์œผ๋กœ ๋‚˜๋ˆˆ ๊ฐ’๊ณผ ๊ฐ™๋‹ค๋Š” ๋ง๊ณผ ๊ฐ™๋‹ค. ๊ฒฐ๊ตญ ๋‰ดํ„ด์˜ ์ œ1๋ฒ•์น™๊ณผ ๊ฐ™์ด, ๋ชจ๋“  ํž˜์˜ ํ•ฉ์ด 0์ด ๋˜๋ฉด ๋ฌผ์ฒด๋Š” ํ‰ํ˜• ์ƒํƒœ(๊ฐ€์†๋„๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ƒํƒœ)๊ฐ€ ๋œ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ํž˜์˜ ์ถ•์ ์ด๋ผ๊ณ  ์•Œ๋ ค์ง„ ํ”„๋กœ์„ธ์Šค๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ์‹ค์ œ๋กœ ๋งค์šฐ ๊ฐ„๋‹จํ•ด์„œ, ๋‹จ์ง€ ๋ชจ๋“  ํž˜์„ ๋”ํ•˜๋ฉด ๋œ๋‹ค.

 

์ด์ œ applyForce() ๋ฉ”์†Œ๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ํž˜์„ ์ถ•์ ํ•˜๋ฉด์„œ ๊ฐ€์†๋„์— ์ƒˆ๋กœ์šด ํž˜์„ ๋”ํ•ด๋ณด์ž.

Mover.prototype.applyForce = function(force) {
    this.acceleration.add(force);
};

 

ํž˜์˜ ์ถ•์ ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ํ•œ ๊ฐ€์ง€๋ฅผ ๋” ํ•ด์•ผ ํ•œ๋‹ค. ๊ณ„์†ํ•ด์„œ ๋ชจ๋“  ํž˜์„ ๋”ํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ๋งค๋ฒˆ update()๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ํ™•์‹คํ•˜๊ฒŒ ๊ฐ€์†๋„๋ฅผ ์—†์• ์•ผ (๊ฐ€์†๋„๋ฅผ 0์œผ๋กœ ์„ค์ •)ํ•œ๋‹ค.

 

๊ฐ ํ”„๋ ˆ์ž„์— ๋Œ€ํ•ด ๊ฐ€์†๋„๋ฅผ ์—†์• ๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ update()์˜ ๋งˆ์ง€๋ง‰ PVector์— 0์„ ๊ณฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Mover.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
};

 

 

 

์งˆ๋Ÿ‰

๋‰ดํ„ด์˜ ์ œ2 ๋ฒ•์น™์€ ์‹ค์ œ๋กœ A = F ๊ฐ€ ์•„๋‹Œ F = MA ๋‹ค. ์งˆ๋Ÿ‰์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์€ ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋งŒํผ ์‰ฝ๋‹ค.

 

์งˆ๋Ÿ‰์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์œผ๋‹ˆ ์ธก์ • ๋‹จ์œ„๋ฅผ ์งš๊ณ  ๋„˜์–ด๊ฐ€๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋‹จ์œ„๋กœ ํ”ฝ์…€๊ณผ ํ”„๋ ˆ์ž„์„ ์‚ฌ์šฉํ•œ๋‹ค.

(ํŽธ์˜๋ฅผ ์œ„ํ•ด ๋ฌผ์ฒด์˜ ์งˆ๋Ÿ‰๊ณผ ํฌ๊ธฐ๋ฅผ ๋ฌถ๋„๋ก ํ•œ๋‹ค. ๋ฌผ์ฒด์˜ ์งˆ๋Ÿ‰์ด 10์ด๋ฉด ๋ฐ˜์ง€๋ฆ„์ด 10์ธ ์›์„ ๊ทธ๋ฆฌ๋Š” ์‹์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฌผ์ฒด์˜ ์งˆ๋Ÿ‰์„ ์‹œ๊ฐํ™”ํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์งˆ๋Ÿ‰์ด ์•ผ๊ธฐํ•˜๋Š” ํšจ๊ณผ๋ฅผ ๊ด€์ฐฐํ•  ์ˆ˜ ์žˆ๋‹ค.)

 

์งˆ๋Ÿ‰์€ ๋ฒกํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์Šค์นผ๋ผ(๋ถ€๋™ ์†Œ์ˆ˜์ )์ด๋‹ค. ์งˆ๋Ÿ‰์€ ์–ด๋–ค ๋ฌผ์ฒด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฌผ์งˆ์˜ ์–‘์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ˆ˜๋‹ค. ๋ฌผ์ฒด์˜ ๋ฉด์ ์„ ์งˆ๋Ÿ‰์œผ๋กœ ๊ณ„์‚ฐํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋ฌผ์ฒด์˜ ์งˆ๋Ÿ‰์„ 10์ด๋ผ๊ณ  ์ •ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๊ฐ„๋‹จํ•ด์ง„๋‹ค.

const Mover = function() {
    this.mass = 10;
    this.position = new PVector(random(width), random(height));
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
};

 

์งˆ๋Ÿ‰์€ ๋‰ดํ„ด์˜ ์ œ2๋ฒ•์น™์„ ๊ฐ์ฒด์— ์ ์šฉํ•  ๋•Œ ์ด์šฉํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ Mover ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์œ„ํ•ด ์ฃผ์˜ํ•  ์ ์ด ์žˆ๋‹ค. JavaScript์—์„œ PVector ๊ฐ™์€ ๊ฐ์ฒด์— ํ• ๋‹น๋œ ๋ณ€์ˆ˜๋Š” ์‚ฌ์‹ค ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” ๊ฐ์ฒด์˜ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ํ•จ์ˆ˜์— ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด, ๋ณต์‚ฌ๋ณธ์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ธฐ์กด์˜ ํฌ์ธํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด(์งˆ๋Ÿ‰์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ฒ˜๋Ÿผ) ๊ทธ ๊ฐ์ฒด๋Š” ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ”๋€๋‹ค. ๋”ฐ๋ผ์„œ ์งˆ๋Ÿ‰์œผ๋กœ ๋‚˜๋ˆ„๊ธฐ ์ „์— PVector f๋ฅผ ๋ณต์‚ฌํ•ด ๋†“์•„์•ผ ํ•œ๋‹ค.

Mover.prototype.applyForce = function(force) {
    const f = force.copy();
    force.div(this.mass);
    this.acceleration.add(f);
};

 

๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š”, ์ด์ „ ๋‹จ์›์—์„œ ๋ฐฐ์šด ์ •์  ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •์  div() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๋ฉ”์†Œ๋“œ๋ฅผ ๋‹ค์‹œ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

Mover.prototype.applyForce = function(force) {
    const f = PVector.div(force, this.mass);
    this.acceleration.add(f);
};

 

์—ฌ๊ธฐ์—์„œ ์ค‘์š”ํ•œ ๊ฒƒ์€, ์—ฌ๋Ÿฌ ๊ฐœ์˜ Mover ๊ฐ์ฒด๋“ค์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ์กด ํž˜ ๋ฒกํ„ฐ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„์•ผ ํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.

 

 

ํž˜์˜ ์ƒ์„ฑ

ํž˜์„ ๋งŒ๋“œ๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ๊ทธ๋ƒฅ ์ˆซ์ž๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

const wind = new PVector(0.01, 0);
const gravity = new PVector(0, 0.1);
mover.applyForce(wind);
mover.applyForce(gravity);

 

์ด์ œ ์„œ๋กœ ๋‹ค๋ฅธ ํฌ๊ธฐ์™€ ๋ฐฉํ–ฅ์„ ๊ฐ–๋Š” ๋‘ ๊ฐœ์˜ ํž˜(๋ฐ”๋žŒ๊ณผ ์ค‘๋ ฅ)์ด ์žˆ๋‹ค. ๋‘ ๊ฐ์ฒด ๋ชจ๋‘ mover๊ฐ์ฒด์— ์ ์šฉํ•œ๋‹ค.

 

๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ๋‹ค ๊ฒฐํ•ฉํ•œ ํ”„๋กœ๊ทธ๋žจ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

 

<canvas id="myCanvas" width="300" height="250" style="border: 1px solid #000;"></canvas>
<script>
    const canvas = document.getElementById('myCanvas');
    const context = canvas.getContext('2d');

    const PVector = function(x, y) {
        this.x = x;
        this.y = y;
    };

    PVector.prototype.add = function(v) {
        this.y = this.y + v.y;
        this.x = this.x + v.x;
    };

    PVector.prototype.mult = function(n) {
        this.x = this.x * n;
        this.y = this.y * n;
    };

    // ๋ฒกํ„ฐ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ
    PVector.prototype.copy = function() {
        return new PVector(this.x, this.y);
    };

    PVector.div = function(v1, n) {
        const v3 = new PVector(v1.x / n, v1.y / n);
        return v3;
    };

    const Mover = function() {
        // ๋ฌผ์ฒด์˜ ์งˆ๋Ÿ‰
        this.mass = 1;
        this.position = new PVector(0, 0);
        this.velocity = new PVector(0, 0);
        this.acceleration = new PVector(0, 0);
    };

    Mover.prototype.update = function() {
        this.velocity.add(this.acceleration);
        this.position.add(this.velocity);
        // ๊ฐ ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๊ฐ€์†๋„ ์ œ๊ฑฐ
        this.acceleration.mult(0);
    };

    Mover.prototype.display = function() {
        context.beginPath();
        // ์งˆ๋Ÿ‰์˜ ์‹œ๊ฐํ™” (์งˆ๋Ÿ‰์— ๋”ฐ๋ผ ํฌ๊ธฐ๋ฅผ ๊ณ„์‚ฐ)
        context.ellipse(this.position.x, this.position.y, this.mass * 20, this.mass * 20, 0, 0, Math.PI * 2, false);
        context.lineWidth = 5;
        context.strokeStyle = '#333333';
        context.stroke();
        context.fillStyle = '#ffffff';
        context.fill();
    };

    // ๊ฐ€์žฅ์ž๋ฆฌ์—์„œ ๊ฐ์ฒด๋ฅผ ํŠ•๊ฒจ๋‚ด๋Š” ๋ฉ”์†Œ๋“œ
    Mover.prototype.checkEdges = function() {
        if (this.position.x > canvas.width) {
            this.position.x = canvas.width;
            this.velocity.x *= -1;
        } else if (this.position.x < 0) {
            this.velocity.x *= -1;
            this.position.x = 0;
        }
        if (this.position.y > canvas.height) {
            this.velocity.y *= -1;
            this.position.y = canvas.height;
        }
    };

    // ๋‰ดํ„ด์˜ ์ œ 2๋ฒ•์น™ (ํž˜์„ ๋ฐ›๊ณ , ์งˆ๋Ÿ‰์œผ๋กœ ๋‚˜๋ˆ„๊ณ , ๊ฐ€์†๋„์— ๋”ํ•จ)
    Mover.prototype.applyForce = function(force) {
        const f = PVector.div(force, this.mass);
        this.acceleration.add(f);
    };

    const mover = new Mover();

    const update = () => {
        context.clearRect(0, 0, canvas.width, canvas.height);

        // ๋ฐ”๋žŒ๊ณผ ์ค‘๋ ฅ ์ ์šฉ
        const wind = new PVector(0.01, 0);
        const gravity = new PVector(0, 0.1);
        mover.applyForce(wind);
        mover.applyForce(gravity);

        mover.update();
        mover.checkEdges();
        mover.display();

        requestAnimationFrame(update);
    };

    update();
</script>

 

 

 

์—ฌ๋Ÿฌ ๋ฌผ์ฒด์˜ ์›€์ง์ž„

์งˆ๋Ÿ‰๊ณผ ์œ„์น˜๊ฐ€ ๋‹ค์–‘ํ•œ, ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฌผ์ฒด์˜ ์›€์ง์ž„์„ ๊ตฌํ˜„ํ•ด๋ณด์ž.

 

 

<canvas id="myCanvas" width="300" height="250" style="border: 1px solid #000;"></canvas>
<script>
    const canvas = document.getElementById('myCanvas');
    const context = canvas.getContext('2d');

    const PVector = function(x, y) {
        this.x = x;
        this.y = y;
    };

    PVector.prototype.add = function(v) {
        this.y = this.y + v.y;
        this.x = this.x + v.x;
    };

    PVector.prototype.mult = function(n) {
        this.x = this.x * n;
        this.y = this.y * n;
    };

    // ๋ฒกํ„ฐ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ
    PVector.prototype.copy = function() {
        return new PVector(this.x, this.y);
    };

    PVector.div = function(v1, n) {
        const v3 = new PVector(v1.x / n, v1.y / n);
        return v3;
    };

    // ๋‹ค์–‘ํ•œ ์งˆ๋Ÿ‰๊ณผ ์œ„์น˜๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด ์ƒ์„ฑ์ž
    const Mover = function(m, x, y) {
        this.mass = m;
        this.position = new PVector(x, y);
        this.velocity = new PVector(0, 0);
        this.acceleration = new PVector(0, 0);
    };

    Mover.prototype.update = function() {
        this.velocity.add(this.acceleration);
        this.position.add(this.velocity);
        // ๊ฐ ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๊ฐ€์†๋„ ์ œ๊ฑฐ
        this.acceleration.mult(0);
    };

    Mover.prototype.display = function() {
        context.beginPath();
        // ์งˆ๋Ÿ‰์˜ ์‹œ๊ฐํ™” (์งˆ๋Ÿ‰์— ๋”ฐ๋ผ ํฌ๊ธฐ๋ฅผ ๊ณ„์‚ฐ)
        context.ellipse(this.position.x, this.position.y, this.mass * 20, this.mass * 20, 0, 0, Math.PI * 2, false);
        context.lineWidth = 5;
        context.strokeStyle = '#333333';
        context.stroke();
        context.fillStyle = '#ffffff';
        context.fill();
    };

    // ๊ฐ€์žฅ์ž๋ฆฌ์—์„œ ๊ฐ์ฒด๋ฅผ ํŠ•๊ฒจ๋‚ด๋Š” ๋ฉ”์†Œ๋“œ
    Mover.prototype.checkEdges = function() {
        if (this.position.x > canvas.width) {
            this.position.x = canvas.width;
            this.velocity.x *= -1;
        } else if (this.position.x < 0) {
            this.velocity.x *= -1;
            this.position.x = 0;
        }
        if (this.position.y > canvas.height) {
            this.velocity.y *= -1;
            this.position.y = canvas.height;
        }
    };

    // ๋‰ดํ„ด์˜ ์ œ 2๋ฒ•์น™ (ํž˜์„ ๋ฐ›๊ณ , ์งˆ๋Ÿ‰์œผ๋กœ ๋‚˜๋ˆ„๊ณ , ๊ฐ€์†๋„์— ๋”ํ•จ)
    Mover.prototype.applyForce = function(force) {
        const f = PVector.div(force, this.mass);
        this.acceleration.add(f);
    };

    const movers = [];

    for (let i = 0; i < 20; i++) {
        // (0, 0) ์œ„์น˜์—์„œ ์‹œ์ž‘ํ•˜๋Š” ๋‹ค์–‘ํ•œ ์งˆ๋Ÿ‰์˜ ๊ฐ์ฒด๋ฅผ 20๊ฐœ ์ƒ์„ฑ
        movers[i] = new Mover(Math.random(0.1, 5), 0, 0);
    }

    const update = () => {
        context.clearRect(0, 0, canvas.width, canvas.height);

        for (let i = 0; i < movers.length; i++) {
            // ๋ฐ”๋žŒ๊ณผ ์ค‘๋ ฅ ์ ์šฉ
            const wind = new PVector(0.01, 0);
            const gravity = new PVector(0, 0.1);
            movers[i].applyForce(wind);
            movers[i].applyForce(gravity);

            movers[i].update();
            movers[i].checkEdges();
            movers[i].display();
        }

        requestAnimationFrame(update);
    };

    update();
</script>

 

์ €์ž‘์žํ‘œ์‹œ
    'note' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [JS] ํž˜ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ 3 | ์นธ ์•„์นด๋ฐ๋ฏธ
    • [JS] ํž˜ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ 2 | ์นธ ์•„์นด๋ฐ๋ฏธ
    • [JS] ๋ฒกํ„ฐ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ 3 | ์นธ ์•„์นด๋ฐ๋ฏธ
    • [JS] ๋ฒกํ„ฐ ๊ฐœ๋… ์ดํ•ดํ•˜๊ธฐ 2 | ์นธ ์•„์นด๋ฐ๋ฏธ
    66651
    66651
    always awake

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”