Giter Site home page Giter Site logo

waterrippleeffect's Introduction

Water Ripple Effect (WRE)

WHAT IS THIS?


Esta é uma biblioteca feita em C++ 20 que simula ondulações de água em uma superfície, você pode tocar a água em qualquer ponto, e ver as ondas se espalharem e refletirem nos limites da superficie.

HOW DOES IT WORK?


A ideia básica é você possuir dois arrays para manter o estado da água, um para o estado atual e o outro para manter o estado do frame anterior.

Aqui está o pseudo-código de como o algoritmo funciona:

damping = some non-integer between 0 and 1

begin loop 
    for every non-edge element:
    loop
        Buffer2(x, y) = (Buffer1(x-1,y)
                         Buffer1(x+1,y)
                         Buffer1(x,y+1)
                         Buffer1(x,y-1)) / 2 - Buffer2(x,y)

        Buffer2(x,y) = Buffer2(x,y) * damping
    end loop

    Display Buffer2
    Swap the buffers 

end loop

Observe que neste caso o Buffer1 contém o estado da agua "atual", e o Buffer2 contém o estado da àgua do frame anterior.

Seguindo esse fluxo:

Buffer 2 -> Buffer1 -> Buffer2 -> ...

Dessa forma, o Buffer2 possui informações sobre a velocidade vertical da onda.

Velocity(x, y) = -Buffer2(x, y)

Para que as ondas se propaguem é necessário que os buffers sejam "suavizados" a cada frame.

Seja SmoothFn(x,y) nossa função de suavização, temos que:

SmoothFn(x,y) = (Buffer1(x-1, y) +
                 Buffer1(x+1, y) +
                 Buffer1(x, y-1) +
                 Buffer1(x, y+1)) / 4

Isso é basicamente a média dos 4 pixels vizinho do ponto (x, y), também chamado de 4-neighborhood.

4-neighborhood: {(x − 1, y), (x, y + 1), (x + 1, y), (x, y − 1)}

Nessa biblioteca utilizamos 8-neighborhood pois resulta em uma suavização melhor da propagação da onda na superficie.

neighborhood.

Agora precisamos calcular a nova altura da onda, a multiplicação por 2 reduz o efeito da velocidade:

new_height = SmoothFn(x,y)*2 + Velocity(x,y)

Por último, as ondulações devem perder energia, por isso são amortecidas por um fator de amortecimento que chamamos de damping:

new_height *= damping

Isso pode ser otimizado para:

new_height = new_height - (new_height >> N)

No qual N é o $\log_2(2^N)$, ou seja, é o logaritmo base 2 de alguma potencia de 2.

ex: 32 == 2⁵, portanto o N = 5;

Veja a seção de referências, ela contém os links para os sites que explicam como todo esse algoritmo funciona em detalhes.

REFERENCES


waterrippleeffect's People

Contributors

fgarcia0x0 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.