Section Curve Interface
Purpose
Define how Buffalo Wings should represent open 2D section geometry alongside closed airfoil bodies. The immediate driver is downstream Panel work that needs both airfoil-derived camber lines and non-airfoil curves such as walls. This document is a design guide for public runtime and schema evolution rather than an implementation diff.
Current State
The existing public airfoil API is still centered on
buffalo_wings.airfoil.Airfoil.
Airfoil inherits the generic Curve base and adds closed-body semantics
such as upper and lower surfaces, a trailing-edge midpoint, and
surface-local xi queries.
The package now exposes a public CamberCurve runtime family and a public
airfoil.camber_curve(...) -> AirfoilCamberResult contract.
OrthogonalAirfoil returns exact native camber through that API because its
geometry is explicitly built from camber and thickness components.
Other constructable families such as SplineAirfoil and CstAirfoil
resolve through the same contract and return deterministic approximate
camber when no exact native camber family is available.
The schema layer now also supports named document-level open curves through
AirfoilDocumentSpec.curves, including airfoil_camber,
spline_curve, and polyline_curve.
On the wing side, WingCanonical.section_curves(...) still consumes
airfoils only through their upper and lower surface queries and has no
parallel path for general open section curves yet.
Problem Statement
The current model treats a closed airfoil body as the main 2D shape unit. That is too narrow for GUI and downstream geometry workflows that need open curves as editable source-of-truth objects. Two open-curve use cases already stand out.
Every airfoil needs an accessible camber-line representation, even when that camber line is only available approximately.
The same editing environment also needs general curves that are not airfoils at all, such as walls, centerlines, or other sectional guide geometry.
If Wings keeps airfoils as the only first-class 2D geometry family, Panel-facing tools will either duplicate curve logic locally or overload the airfoil interface with concepts that do not belong to closed bodies.
Design Goals
Preserve
Airfoilas the closed-body interface.Add a first-class public model for open 2D section curves.
Make exact camber available when an airfoil family has a natural camber decomposition.
Make approximate camber available for every constructable airfoil family.
Keep schema documents as the source of truth for GUI editing and saved work.
Let future wing and Panel workflows consume curves without importing internal airfoil modules.
Recommended Runtime Model
The existing generic Curve geometry contract should remain the mathematical foundation.
The missing piece is a public persisted open-curve family that sits beside Airfoil rather than underneath it.
1. Public Open-Curve Base
Use the existing public Curve contract as the shared geometric base for
open section geometry.
If a later API pass still needs a more explicit public SectionCurve
family for naming or persistence purposes, it should layer on top of this
same query contract rather than introducing a parallel geometry interface.
2. Public Camber Subtype
The current public CamberCurve family is the specialized open section
curve subtype for airfoil mean lines.
It carries these constraints:
the native parameter domain is
[0, 1],x = uby definition,the curve runs from the leading-edge reference to the trailing-edge reference,
and it remains suitable for chordwise queries used by aerodynamic tooling.
The current internal Camber base remains the implementation starting
point for concrete chordwise camber runtimes.
3. Airfoil-to-Camber Access
Every public airfoil should be able to provide a camber curve. That interface is now explicit and encodes whether the result is exact or approximate through a small result object so downstream tools can preserve provenance.
Recommended contract:
airfoil.camber_curve(...) -> AirfoilCamberResultAirfoilCamberResult.curve: CamberCurveAirfoilCamberResult.mode: "exact" | "approximate"AirfoilCamberResult.source_family: str
For orthogonal airfoils, mode should be "exact" and curve should expose the native camber object.
For spline, CST, and future point-backed airfoils, mode may be "approximate" until an exact family-specific construction is available.
4. Approximate Camber Policy
Approximate camber should be treated as a supported, explicit workflow rather than as an implementation embarrassment. The current approximation policy is deterministic and easy to explain.
The recommended initial approach is:
sample both airfoil surfaces at a shared monotone
xidistribution,compute the midpoint between upper and lower coordinates at each
xi,fit or interpolate those points into a
CamberCurve,report the approximation mode and any fit-quality diagnostics.
That policy is simple, family-agnostic, and already aligns with the current sampling-oriented downstream workflows. It also preserves a clean path to later family-specific exact constructions for spline or CST families if those become important.
Recommended Schema Model
Open curves should have first-class schema definitions instead of being forced through airfoil-only documents. The most useful near-term document shape is a shared geometry document that can hold both closed airfoils and open curves by name.
Recommended top-level direction:
schema_version: 1
airfoils: {}
curves: {}
The curves map should hold named open-curve definitions that can be edited directly, referenced by GUI tools, and reused by downstream geometry workflows.
Curve Families
The initial schema surface should stay narrow and practical. The first useful families are:
airfoil_camberfor a curve derived from a named airfoil,spline_curvefor an authored open spline or Bezier curve,points_curvefor an authored polyline or fitted point-backed open curve,and
cst_curveif a one-sided CST definition becomes useful for walls or guide shapes.
Airfoil-Derived Camber Specs
An airfoil-derived camber line should remain linked to its source airfoil in schema rather than being flattened immediately into points. That keeps GUI edits synchronized when the user changes the source airfoil.
Recommended shape:
curves:
root_camber:
type: airfoil_camber
airfoil: root
mode: exact_or_approximate
approximation:
spacing: cosine
num_points: 81
fit: spline
The exact field names can evolve, but the important design choice is that derived camber remains a derived schema object with stable provenance.
Why This Should Live Beside Airfoils
General walls and guide curves are not airfoils. They should not inherit trailing-edge semantics, upper and lower surface concepts, or airfoil-specific inverse-parameter helpers. At the same time, they belong in the same local section-geometry ecosystem because they share the same 2D query math, editor affordances, and downstream consumers.
That makes SectionCurve a sibling of Airfoil, not a special airfoil subtype and not a completely unrelated package.
Downstream Integration
This split helps two major downstream paths immediately.
Panel-Facing Work
Panel tools can request an airfoil camber line without caring whether the answer was exact or approximate. The same tools can also consume named wall curves from the same document without pretending those walls are closed bodies. That removes pressure to keep local-only curve representations inside Panel.
Wing-Facing Work
WingCanonical can continue to use upper and lower airfoil surfaces for section-body generation.
Later wing work can add optional open-curve consumers for guide curves, join lines, or reference section constructions without changing the core airfoil contract again.
Phased Implementation Order
The smallest useful delivery order was:
Expose a public
CamberCurveAPI from the existing internal curve and camber foundations.Add
Airfoil.camber_curve(...)with exact results for orthogonal airfoils and deterministic approximate results for the other constructable families.Add public examples and diagnostics for approximate camber extraction.
Add schema support for named open curves, starting with
airfoil_camber,spline_curve, andpolyline_curve.
The next useful delivery step is:
Extend Panel and future GUI workflows to consume both
airfoilsandcurvesfrom schema-backed documents.
Non-Goals
This design does not require every curve family to share airfoil-style u_from_x(...) helpers.
This design does not require exact camber reconstruction for every runtime family in the first slice.
This design does not require wing work to stop using the current upper and lower airfoil surface contract.
This design also does not commit the project to a standalone top-level buffalo_wings.curve package before there is a broader need outside section geometry.
Recommendation
The next implementation slice should shift from core curve-model plumbing to
downstream consumption:
use the now-public camber and document-curve APIs to drive one end-to-end
schema-backed Panel or GUI workflow.
That delivers immediate user value while pressure-testing whether the
current Curve-based public surface is enough or whether a more explicit
SectionCurve family is still worth introducing later.