SWMMVis  6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
polylineoffset.h File Reference

Perpendicular polyline offset — closes the Z.5 offset gap (Z.5b). More...

#include <QPolygonF>
Include dependency graph for polylineoffset.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Namespaces

namespace  OpenSWMM
 
namespace  OpenSWMM::Render
 

Functions

QPolygonF OpenSWMM::Render::offsetPolyline (const QPolygonF &input, qreal offsetPx, qreal miterLimit=kDefaultMiterLimit)
 Offset input perpendicular to each segment by offsetPx.
 

Variables

constexpr qreal OpenSWMM::Render::kDefaultMiterLimit = 2.0
 Default miter limit (length ratio) before the algorithm falls back to a bevel join. Mirrors QPen's default of 2.0 — a miter is rejected when its length exceeds 2× the offset distance. Lower → more bevels; higher → spikier joins at sharp angles.
 

Detailed Description

Perpendicular polyline offset — closes the Z.5 offset gap (Z.5b).

Author
Caleb Buahin caleb.nosp@m..bua.nosp@m.hin@g.nosp@m.mail.nosp@m..com
Date
2026
License\n GPL-3.0-or-later
    LineSymbolLayerSpec::offsetPx (Slice Z.5) ships the field but
    doesn't apply it at paint time — the helper for that lives
    here. The algorithm shifts every segment perpendicular to its
    own direction by \p offsetPx pixels (positive = right of
    forward direction), then joins the shifted segments at each
    interior vertex.

    Join handling:
      - Interior vertices use a **miter** join — the intersection
        of the two shifted segments. When the miter length would
        exceed \ref kDefaultMiterLimit times \p offsetPx (sharp
        angles, near-fold cases), the algorithm falls back to a
        **bevel** join: it emits two points (the shifted end of
        segment N and the shifted start of segment N+1) rather
        than the single miter intersection. This prevents the
        extreme spikes that pure miters produce at sharp angles.
      - Endpoints use the perpendicular of their single adjacent
        segment.

    Degenerate input handling:
      - Empty polyline → empty result.
      - Single vertex → unchanged (one-vertex polylines have no
        direction).
      - Zero \p offsetPx → identical input (no normal shift).
      - Two vertices coincident → that segment is skipped at join
        time; the perpendicular falls back to the previous valid
        segment.

    The helper is a pure function; no Qt painter state involved.
    Callers can wire it into `LineSymbolLayerSpec::offsetPx`
    consumers at paint time without further plumbing.