A small immutable struct representing river width along a curve, storing start width, end width and curve length, providing eased interpolation of width and helper accessors.
using System;
namespace RedSnail.WaterTool2;
/// <summary>
/// How wide a river is along its curve: its width at each end, eased from one to the other so the banks leave and
/// arrive without a kink. Water is level across a river, so a river is symmetric about its centreline.
/// </summary>
public readonly struct RiverWidth
{
/// <summary>
/// No river is built narrower than this: two banks on one point make faces with no area.
/// </summary>
public const float Min = 16.0f;
public readonly float Start;
public readonly float End;
public readonly float Length;
public RiverWidth(float _Start, float _End, float _Length)
{
Start = MathF.Max(Min, _Start);
End = MathF.Max(Min, _End);
Length = MathF.Max(0.001f, _Length);
}
/// <summary>
/// The furthest a bank gets from the centreline anywhere along the river.
/// </summary>
public float MaxHalf => MathF.Max(Start, End) * 0.5f;
/// <summary>
/// The full width at a curve distance.
/// </summary>
public float At(float _Distance)
{
if (Start == End)
return Start;
float t = Math.Clamp(_Distance / Length, 0.0f, 1.0f);
t = t * t * (3.0f - 2.0f * t);
return Start + (End - Start) * t;
}
/// <summary>
/// How far each bank sits from the centreline at a curve distance.
/// </summary>
public float HalfAt(float _Distance)
{
return At(_Distance) * 0.5f;
}
public void AddToHash(ref StableHash _Hash)
{
_Hash.Add(Start);
_Hash.Add(End);
_Hash.Add(Length);
}
}