Source code for lsurf.surfaces.cpu.wave_params

# The Clear BSD License
#
# Copyright (c) 2026 Tobias Heibges
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted (subject to the limitations in the disclaimer
# below) provided that the following conditions are met:
#
#      * Redistributions of source code must retain the above copyright notice,
#      this list of conditions and the following disclaimer.
#
#      * Redistributions in binary form must reproduce the above copyright
#      notice, this list of conditions and the following disclaimer in the
#      documentation and/or other materials provided with the distribution.
#
#      * Neither the name of the copyright holder nor the names of its
#      contributors may be used to endorse or promote products derived from this
#      software without specific prior written permission.
#
# NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
# THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

"""
Gerstner Wave Parameters

Dataclass for configuring individual Gerstner wave components.
Used by both GerstnerWaveSurface and CurvedWaveSurface.
"""

from dataclasses import dataclass

import numpy as np


[docs] @dataclass class GerstnerWaveParams: """ Parameters for a single Gerstner wave component. Gerstner waves describe the motion of water particles in circular orbits, producing realistic wave shapes with sharp crests and flat troughs. Parameters ---------- amplitude : float Wave amplitude (vertical displacement) in meters. wavelength : float Wave wavelength (crest-to-crest distance) in meters. direction : tuple of float, optional Wave propagation direction as (dx, dy), will be normalized. Default is (1.0, 0.0) for propagation in +x direction. phase : float, optional Initial phase offset in radians. Default is 0.0. steepness : float, optional Wave steepness Q (0 to 1). Controls horizontal displacement. Q=0 gives pure vertical sinusoidal motion. Q=1 gives maximum sharpening (breaking wave limit). Default is 0.5. Attributes ---------- wave_number : float Wave number k = 2π/λ in radians per meter. angular_frequency : float Angular frequency from deep water dispersion: ω = √(gk). direction_normalized : tuple of float Normalized direction vector. Examples -------- >>> # Simple wave propagating in +x direction >>> wave = GerstnerWaveParams(amplitude=1.0, wavelength=50.0) >>> # Steep wave at 45 degrees >>> wave = GerstnerWaveParams( ... amplitude=2.0, ... wavelength=30.0, ... direction=(1.0, 1.0), ... steepness=0.8 ... ) """ amplitude: float wavelength: float direction: tuple[float, float] = (1.0, 0.0) phase: float = 0.0 steepness: float = 0.5 @property def wave_number(self) -> float: """Wave number k = 2π/λ.""" return 2.0 * np.pi / self.wavelength @property def angular_frequency(self) -> float: """Angular frequency from deep water dispersion: ω = √(gk).""" g = 9.81 # gravitational acceleration m/s² return np.sqrt(g * self.wave_number) @property def direction_normalized(self) -> tuple[float, float]: """Normalized direction vector.""" norm = np.sqrt(self.direction[0] ** 2 + self.direction[1] ** 2) if norm < 1e-10: return (1.0, 0.0) return (self.direction[0] / norm, self.direction[1] / norm)