3
\$\begingroup\$

The gerstner wave function is a commonly used method to calculate waves and simulate water in video games and movies or most 3d simulations. It is however quite complex so it is very hard for young developers such as myself to understand and implement it into code.

Would it be possible to simplify the formula:

  • A = amplitude of wave (Float)
  • W = wave number (Vector)
  • D = direction (Vector) how do i know what to set the direction to?
  • S = Speed
  • L = wave length
  • phase-constant = S x 2* pi/L.

According to the article Q = 1/(W * A)

enter image description here

Issues and Questions:

  • Why are all three lines of the formula seperated by commas?
  • D refers to a directional vector (i think)
  • Q = 1/(W * A) but W is a vector and A is a float?
  • What does this line mean: wiDi.(x,y) is that reffering to w * dot product of(d , (x,y))
    • sigma returns the sum of what exactly?

Here is my attempt to implement it into java code:

float yPos = (float) ((steepness * amplitude) * direction.y * Math.cos(wavenumber.y * (direction.dot(position)) + phase_const * time));

Dont know if its correct

This may help:

https://github.com/armanuguray/water-surface/blob/master/src/engine/waterengine.cpp

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Here’s a tip: the common typographic convention for vectors is to use boldface. \$\endgroup\$ Commented Feb 4, 2014 at 11:16
  • 1
    \$\begingroup\$ I spend some time figuring this out, and ended up writing a post about it with very simplified, yet complete code here gerstner wave ocean. \$\endgroup\$
    – mujtaba-io
    Commented Dec 7, 2023 at 13:40

1 Answer 1

5
\$\begingroup\$

Why are all three lines of the formula seperated by commas?

  • P(x,y,t) is a vector valued function. Its values are thus 3D vectors. The commas just separate these components, probably akin to a Matlab style of coding.

D refers to a directional vector (i think)

  • D is a 2D vector in the (x,y) plane. It describes the direction (and magnitude, if not noramlized!) of a principal wave component. Several such components (D_is) are actually added together, as seen in the formula, to equate the desired wavy/wobbly effect. It's akin to a Fourier decomposition of a signal into A sine + B cosine polynomials

Q = 1/(W * A) but W is a vector and A is a float?

  • W_i and A_i are both scalars! (1D values!). The A_i is the wave amplitude or height, whereas W_i should control the wave's sharpness (more pronounced crests)

What does this line mean: wiDi.(x,y) is that reffering to w * dot product of(d , (x,y)) sigma returns the sum of what exactly?

  • W_i multiplies the dot(Di,(x,y)). Thus the dot is taken between the wave direction and the current grid position, (x,y). This dot product appears in the arguments of two trig functions (cos and sin), and it is present in there to introduce a phase difference into the waves, otherwise all points on the surface of the wave would have the same water level height (this explanation is a layman's view of something a bit more complicated - I can't fit the whole explanation here :( ).

Your pseudocode is looking ok-ish. It should actually be written as:

yPos += (float) ((steepness[i] * amplitude[i]) * direction[i].y * Math.cos(w[i] * (direction[i].dot(position[i])) + phase_const[i] * time));

..that is, you need at least N=2 (i=0,1,..N) different wave directions for something more interesting to develop, otherwise you're going to end up with a sine-like wave (pretty bland looking).

\$\endgroup\$

You must log in to answer this question.