Matemática para games – Bézier

Não somos seres perfeitos, longe disso, e por isso nos deparamos muitas vezes com uma situação onde a “máquina” deve entrar em ação e corrigir nossas falhas. Em muitos jogos temos que traçar um caminho para, por exemplo, um personagem seguir, porém fazer um traçado “bonito” usando o mouse ou o dedo não é uma tarefa fácil.

Flight Control e Spy Mouse

Para contornar essa situação, podemos usar o conceito matemático da Curva de Bézier, que foi originalmente desenvolvido pelo francês Pierre Bézier, na década de 60, para a indústria automobilística,  para desenhar o contorno suave dos carros modernos em computadores.

Linear

B(t) = (1 – tPtP1

Quadrática

B(t) = (1 – t)² P+ 2(1 – t)tP+ t²P2

Cúbica

B(t) = (1 – t)³ P+ 3(1 – ttP+ 3(1 – t)t²P2 + t³P3

Algoritmo de deCasteljau

É um método recursivo para calcular  a curva de Bézier entre 2 ou mais pontos de controle.


Primeiramente, temos que criar um ambiente onde possamos pegar alguns pontos de controle, conforme o trajeto é desenhado. Ao clicar na tela será adicionado um ponto de controle, após isso, ao mover o mouse (pressionado) serão adicionados novos pontos de controle até que o mouse seja “solto”. A cada ponto adicionado, a curva, será calculada e re-desenhada.

Obs.: Usei 1600 porque é o quadrado de 40 (40 * 40), para mais detalhes, ver o post sobre distância entre dois pontos.

Com os pontos de controle em mãos, podemos partir para a ação. Definiremos a quantidade de smoothness (suavidade) desejada para a curva.

Abaixo segue um exemplo usando o algoritmo de deCasteljau. Use o W e S para aumentar ou diminuir a suavidade (smoothness). Use o D para exibir ou esconder os pontos. E o A para usar pontos de controles fixos ou mutáveis (onde os pontos de controle mudam de posição, levando em consideração os últimos pontos adicionados e a curva obtida).

O projeto completo está no Github.

Referencias:

Bézier Curves for your Games: A Tutorial
Bezier Spline Curves

  • Thiago M

    como seria em lua? →

    // t (float entre 0 e 1) e dois pontos[x,y]
    function linearBezier(t, p0, p1) {
    // variavel auxiliar
    var u = 1 – t;

    var b = new Vector2();
    b.x = u*p0.x + t*p1.x;
    b.y = u*p0.y + t*p1.y;
    return b;
    }

    • Maicon Feldhaus

      — t (float entre 0 e 1) e dois pontos[x,y]
      local function linearBezier(t, p0, p1)
      — variavel auxiliar
      local u = 1 – t;

      local b = { x=0, y=0 }
      b.x = u*p0.x + t*p1.x
      b.y = u*p0.y + t*p1.y
      return b
      end

      local p0 = { x=100, y=100 }
      local p1 = { x=200, y=350 }
      display.newLine( p0.x, p0.y, p1.x, p1.y )

      for i=0, 10 do
      local p = linearBezier( i/10, p0, p1 )
      local c = display.newCircle( p.x, p.y, 5 )
      c.fill = { 1, 0, 0 }
      end

  • Pingback: Aprenda a fazer Curvas de Bézier para os seus games |()