Code/Geometry/RiverWidth.cs

Struct that represents river width along a curve, storing start width, end width and curve length. It enforces minimums, evaluates eased width at a distance and provides half-width and hashing support.

File Access
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);
	}
}