[TIL] 2019-10-16

undefcat·2019년 10월 15일
0

TIL

목록 보기
28/228

알고리즘

종만북

  • 9.4 - 광학 문자 인식
    - 넘모 어렵다... 해설을 봐도 어렵다... 해설 봤으니 내일 다시 풀자.

Coding Math

11. Gravity

중력은 G*M/r^2이지만 중력상수 G는 매우 작기도 하고, 어차피 게임 프로그래밍 등에서는 이러한 값이 큰 영향을 주는게 아니라면 무시해도 되니까 보통은 M/r^2으로 생각하면 된다.

태양과 지구를 생각했을 때, 지구의 속도벡터에 태양과의 중력벡터를 더하면 새로운 지구의 속도벡터가 생기는데, 이를 단순하게 코딩하면 된다.

import Vector from './Vector.js'

// 속도를 가진 입자 클래스
export default class Particle {
  public mass: number = 1

  readonly pos: Vector
  readonly velocity: Vector

  constructor(x: number, y: number, speed: number, angle: number) {
    const pos = new Vector(x, y)
    const velocity = new Vector(0, 0)

    velocity.length = speed
    velocity.angle = angle

    this.pos = pos
    this.velocity = velocity
  }

  get x(): number {
    return this.pos.x
  }

  get y(): number {
    return this.pos.y
  }

  update() {
    this.pos.addTo(this.velocity)
  }

  distanceTo(p: Particle): number {
    const x = p.x - this.x
    const y = p.y - this.y

    return Math.sqrt(y*y + x*x)
  }

  angleTo(p: Particle): number {
    return Math.atan2(p.y - this.y, p.x - this.x)
  }

  gravitateTo(p: Particle) {
    // 중력벡터
    const gravity = new Vector(0, 0)
    const dist = this.distanceTo(p)
    const angle = this.angleTo(p)

    // 중력의 크기
    // M/r^2
    gravity.length = p.mass / (dist*dist)
    
    gravity.angle = angle

    this.velocity.addTo(gravity)
  }
}
import Particle from './Particle.js'

const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')

const w = window.innerWidth
const h = window.innerHeight

canvas.width = w
canvas.height = h

const sun = new Particle(w/2, h/2, 0, 0)

// 여기서 행성의 최초 각도가 -Math.PI/2인데, 이는
// 최초에 원심력의 방향이어야 하기 때문이다.
// 즉, 태양과 90도를 이루는 각도여야 한다.
const planet = new Particle(w/2 + 200, h/2, 10, -Math.PI/2)

sun.mass = 40000

function update() {
  ctx.clearRect(0, 0, w, h)

  planet.update()
  planet.graviateTo(sun)

  ctx.beginPath()
  ctx.fillStyle = '#ff0000'
  ctx.arc(sun.x, sun.y, 30, 0, Math.PI*2, false)
  ctx.fill()

  ctx.beginPath()
  ctx.fillStyle = '#0000ff'
  ctx.arc(planet.x, planet.y, 10, 0, Math.PI*2, false)
  ctx.fill()

  requestAnimationFrame(update)
}

update()
profile
undefined cat

0개의 댓글