A simple immutable value type that represents a local coordinate frame for an arch or path segment in the editor. It stores position, basis vectors (Along, Across, Up), and some scalar properties, and provides convenience accessors to compute side positions, a 2D flat position, and yaw in degrees.
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;
namespace Sunless.Architecture;
// Across is the RIGHT of travel, so positive offset is the same side everywhere.
public readonly struct ArchFrame
{
public Vector3 Position { get; init; }
public Vector3 Along { get; init; }
public Vector3 Across { get; init; }
public Vector3 Up { get; init; }
public float Distance { get; init; }
public float WidthScale { get; init; }
public Vector3 Side( float offset ) => Position + Across * offset;
public Vector3 Side( float offset, float lift ) => Position + Across * offset + Up * lift;
public Vector2 Flat => new( Position.x, Position.y );
public float Yaw => MathF.Atan2( Along.y, Along.x ).RadianToDegree();
}