moonclip

    Integer and decimal polygon Boolean, PolyTree, offset, stroke, simplification and Minkowski Sum for MoonBit

    geometry
    polygon
    Download zip
    Version
    0.4.0
    License
    BSL-1.0
    Last updated
    10 days ago
    Downloads
    72

    No dependencies

    #MoonClip

    MoonClip 是用 MoonBit 实现的二维多边形几何库,提供整数和十进制网格上的小数运算。运行库不依赖 C++ 或其他几何运行时。

    #安装与使用

    moon add BigSaltyMan/moonclip@0.4.0

    自 0.4.0 提供开放折线区域求交、求差和闭合中心线描边,整数/小数使用一致的调用契约。运行库不增加依赖,固定工具链不变。安装命令按目标版本给出;各版本变更见 CHANGELOG。0.3.2 的发布、注册表和中文链接验证仍归属原发布记录,不转记为 0.4.0 的安装证据。

    在包的 moon.pkg 中导入 BigSaltyMan/moonclip;可参考受检的示例配置和 CLI 示例。已发布的 Boolean、Offset、单路线 Stroke、显式简化及基础几何见支持范围;0.2.0 增加的树接口见旧树接口升级说明。

    #0.4.0 新增能力

    任务整数/小数入口结果
    开放路线保留区域内intersect_polylines/intersect_polylines_d内部及最终边界上的有序开放片段
    开放路线区域擦除difference_polylines/difference_polylines_d外部及孔洞中的有序片段,剔除正长度边界重合区间
    闭合中心线描边stroke_closed_polyline/stroke_closed_polyline_d平铺覆盖区域,可以有孔洞
    闭合描边层级stroke_closed_tree/stroke_closed_tree_d同次清理生成的孔洞树,可单点/批量查询

    路线输出保持方向、顺序及有效中间点;求差的切分端点仍可在边界,不能称所有输出点严格位于外部。统一边界包含/排除规则是 MoonClip 契约,不宣称与 Clipper2 所有特殊贴边分支一致。小数路线和区域共同量化,只有区域接受闭合有效性检查,数值路线见区域裁线。

    闭合描边隐式连接中心线末首,没有端点参数,不等于已填充区域的偏移;树直接来自最终清理,不作第二次公开求值。没有批量闭合入口或闭合模式简化,见组合与闭合描边。每次公开调用独立建账,内部阶段共享预算,不重置或退款。

    网页已接入整数/小数区域裁线求交与求差、闭合描边平铺/树及树查询;SVG 只导出结果,JSON 沿用区域 v1、树 v2、开放片段 v3。

    #既有能力(自 0.3.0 或更早)

    能力整数小数输出使用说明
    开放折线窗口裁剪支持支持有序开放片段窗口裁剪
    闭合区域窗口裁剪支持支持平铺/孔洞树窗口裁剪
    多路线批量描边支持支持平铺/孔洞树组合流程
    Minkowski Sum支持支持平铺/孔洞树图案扫掠
    树单点/批量定位支持支持定位状态与命中节点树点定位

    整数平铺 minkowski_sum 已在 0.1.0 提供;表中小数、树及其他增量的发布边界见源码升级说明。详细接口以生成接口为准,CHANGELOG按版本记录变化。

    #从源码开始使用

    使用固定工具链,Windows 的 shell 脚本通过 Git Bash 执行:

    git clone https://github.com/BigSaltyMan/moonclip.git cd moonclip moon run --target native cmd/example

    cmd/example/main.mbt 包含完整轮廓、孔洞、复制隔离、错误和查询断言,是源码 API 的使用起点。需要迁移现有调用时,先阅读增量升级说明,再按任务进入专题文档。

    Point64 保存 Int64,几何计算接受每轴 ±1,000,000,000;PointD 使用 Precision 0—6(默认 3)量化到同一整数网格,原单位范围随精度缩小。几何输入的量化合并可能报错,查询点量化重合则允许。计算返回 Result,失败不修改输入或发布部分结果;合法坐标和输入数量也可能因内部累计预算而被拒绝。数值与所有权契约见支持范围、数值路线和小数适配。

    #浏览器演示

    cd demo npm run dev

    服务启动后打开 http://127.0.0.1:4173/。Boolean、Offset、单路线描边、批量描边、闭合窗口裁剪及 Minkowski 六类区域树均支持整数/小数、层级查看、节点高亮和单点/批量定位。开放窗口裁剪返回开放片段;开放片段和平铺结果不支持树查询。

    小数定位使用本次建树 Precision,靠近边界的点可能量化到边界;页面标记仍显示原始输入坐标。JSON 保存真实请求和结果:平铺区域 v1、孔洞树 v2、开放片段 v3;SVG 按区域或开放线条导出。启动、操作及协议见演示说明,历史下载重放与窄屏观察见浏览器验收。

    #验证证据与检查入口

    完整回归归属 339947be1cb0ac87ab3a16b9658093806d0a4736:Windows/Linux 的 native、JS 分别 2427/2427,conformance 工具 294 项、桥接 31/31,见完整验收和该 SHA CI。本版本候选仅另做版本、实际包内容和外部消费者检查,不能写成候选 SHA 重新全量通过。历史定向及浏览器证据保留各自提交归属,参考目录 1416 个案例、2308 项能力检查不代表新增八接口已有逐项上游对照。

    普通 CI 按 CHECK_SCOPE 选择文档、核心、演示或包检查范围;发布源码、状态文档和文档修正版候选的证据按各自提交与 scope 记录,package 或 docs 成功均不表示完整回归通过。完整检查入口仍保留,需显式选择;实际执行范围见工作流与检查脚本。文档检查只验证指定材料的本地链接目标存在和差异空白,不构建或执行几何:

    bash scripts/check.sh --scope docs

    性能报告保留原测量提交的 Windows native 基线,不能作为新增功能的性能结论。发布、候选消费者及历史树验收分别见0.3.0 发布记录与旧树验收。

    #来源与许可

    固定参考 Clipper2 2.0.1 / Clipper2_2.0.1 / 21ebba05db8894f0c7217ad35ea518080f324946,采用 BSL-1.0。C# 是主要引擎阅读与移植参考;固定 C++ 适配器用于生成、复核测试数据,运行库不依赖它。普通 CI 不下载或构建 C++ 参考。移植范围、自有适配和上游关系见来源说明、相关工作及许可证。

    Path64

    type Path64 = Array[Point64]

    An ordered, mutable point array. No normalization is implicit.

    PathD

    type PathD = Array[PointD]

    An Array is a collection of values that supports random access and can grow in size.

    Paths64

    type Paths64 = Array[Array[Point64]]

    An ordered, mutable path array; paths may be empty or share storage.

    PathsD

    type PathsD = Array[Array[PointD]]

    An Array is a collection of values that supports random access and can grow in size.

    Axis

    pub(all) enum Axis {
    X
    Y
    } derive(Eq,
    Debug
    )

    Bounds64

    pub(all) struct Bounds64 {
    min_x : Int64
    min_y : Int64
    max_x : Int64
    max_y : Int64
    } derive(Eq,
    Debug
    )

    BoundsD

    pub(all) struct BoundsD {
    min_x : Double
    min_y : Double
    max_x : Double
    max_y : Double
    } derive(Eq,
    Debug
    )

    Raw immutable decimal window parameters; geometry entry points validate them.

    CapType

    pub(all) enum CapType {
    Butt
    Square
    Round
    } derive(Eq,
    Debug
    )

    ClipError

    pub(all) enum ClipError {
    InvalidInput(ErrorLocation, String)
    CoordinateOutOfRange(ErrorLocation, Axis, Int64)
    ExecutionFailure(ErrorLocation, String)
    NumericFailure(ErrorLocation, String)
    ResourceLimitExceeded(ErrorLocation, ResourceKind, Int)
    QuantizationFailure(ErrorLocation, Axis?, ErrorLocation?, String)
    DecimalCoordinateOutOfRange(ErrorLocation, Axis, Double, Int)
    } derive(Eq,
    Debug
    )

    Errors are returned as values; messages are English.

    ClipError::message

    fn ClipError::message(self : ClipError) -> String

    ClipType

    pub(all) enum ClipType {
    Intersection
    Union
    Difference
    Xor
    } derive(Eq,
    Debug
    )

    ErrorLocation

    pub(all) struct ErrorLocation {
    stage : Stage
    path_index : Int?
    vertex_index : Int?
    } derive(Eq,
    Debug
    )

    Indices are zero-based in the original input, before normalization.

    FillRule

    pub(all) enum FillRule {
    EvenOdd
    NonZero
    } derive(Eq,
    Debug
    )

    JoinType

    pub(all) enum JoinType {
    Miter
    Bevel
    Square
    Round
    } derive(Eq,
    Debug
    )

    Limits

    pub(all) struct Limits {
    max_input_paths : Int
    max_input_vertices : Int
    } derive(Eq,
    Debug
    )

    impl Default for Limits

    OffsetOptions

    pub struct OffsetOptions {
    join : JoinType
    miter_limit : Double
    arc_tolerance : Double
    } derive(Eq,
    Debug
    )

    OffsetOptions::new

    fn OffsetOptions::new(join? : JoinType, miter_limit? : Double, arc_tolerance? : Double) -> OffsetOptions

    Orientation

    pub(all) enum Orientation {
    CounterClockwise
    Clockwise
    Collinear
    } derive(Eq,
    Debug
    )

    PathMode

    pub(all) enum PathMode {
    Open
    Closed
    } derive(Eq,
    Debug
    )

    Point64

    pub(all) struct Point64 {
    x : Int64
    y : Int64
    } derive(Eq,
    Debug
    )

    An immutable integer point. Coordinates are stored without floating-point conversion.

    Point64::new

    fn Point64::new(x : Int64, y : Int64) -> Point64

    Construct a point without restricting the Int64 storage range.

    PointD

    pub(all) struct PointD {
    x : Double
    y : Double
    } derive(Eq,
    Debug
    )

    Raw immutable floating-point storage; geometry entry points validate and quantize.

    PointD::new

    fn PointD::new(x : Double, y : Double) -> PointD

    PointLocation

    pub(all) enum PointLocation {
    Outside
    Inside
    OnBoundary
    } derive(Eq,
    Debug
    )

    PolyNode64

    pub struct PolyNode64 {
    // private fields
    }

    PolyNode64::children

    fn PolyNode64::children(self : PolyNode64) -> Array[PolyNode64]

    PolyNode64::contour

    fn PolyNode64::contour(self : PolyNode64) -> Array[Point64]

    PolyNode64::depth

    fn PolyNode64::depth(self : PolyNode64) -> Int

    PolyNode64::is_hole

    fn PolyNode64::is_hole(self : PolyNode64) -> Bool

    PolyNodeD

    pub struct PolyNodeD {
    // private fields
    }

    PolyNodeD::children

    fn PolyNodeD::children(self : PolyNodeD) -> Array[PolyNodeD]

    PolyNodeD::contour

    fn PolyNodeD::contour(self : PolyNodeD) -> Array[PointD]

    PolyNodeD::depth

    fn PolyNodeD::depth(self : PolyNodeD) -> Int

    PolyNodeD::is_hole

    fn PolyNodeD::is_hole(self : PolyNodeD) -> Bool

    PolyTree64

    pub struct PolyTree64 {
    // private fields
    }

    PolyTree64::locate

    fn PolyTree64::locate(self : PolyTree64, point : Point64, limits? : Limits) -> Result[TreePointLocation64, ClipError]

    Since 0.3.0: locate an integer point using existing contour depths. Limits count tree contours/vertices; worst-case linear in all contour vertices.

    PolyTree64::locate_many

    fn PolyTree64::locate_many(self : PolyTree64, points : Array[Point64], limits? : Limits) -> Result[Array[TreePointLocation64], ClipError]

    Since 0.3.0: locate integer points in input order with one shared query budget. Limits count tree contours/vertices; error vertex_index identifies the query point.

    PolyTree64::roots

    fn PolyTree64::roots(self : PolyTree64) -> Array[PolyNode64]

    A new array of immutable node views; virtual root has no contour.

    PolyTree64::to_paths

    fn PolyTree64::to_paths(self : PolyTree64) -> Array[Array[Point64]]

    Copies every contour and both array levels. Ordering is unspecified.

    PolyTreeD

    pub struct PolyTreeD {
    // private fields
    }

    Immutable topology from the quantized integer region. Introduced in 0.2.0.

    PolyTreeD::locate

    fn PolyTreeD::locate(self : PolyTreeD, point : PointD, limits? : Limits) -> Result[TreePointLocationD, ClipError]

    Since 0.3.0: quantize a point with this tree's original Precision, then locate exactly.

    PolyTreeD::locate_many

    fn PolyTreeD::locate_many(self : PolyTreeD, points : Array[PointD], limits? : Limits) -> Result[Array[TreePointLocationD], ClipError]

    Since 0.3.0: ordered queries share one temporary grid view and budget. Query points may quantize together; error vertex_index identifies the query point.

    PolyTreeD::roots

    fn PolyTreeD::roots(self : PolyTreeD) -> Array[PolyNodeD]

    Returns a fresh array of immutable views. Root contours have depth one.

    PolyTreeD::to_paths

    fn PolyTreeD::to_paths(self : PolyTreeD) -> Array[Array[PointD]]

    Copies both array levels; explicit parent-child relationships are discarded.

    Precision

    pub struct Precision {
    // private fields
    } derive(Eq,
    Debug
    )

    Immutable decimal digits. Construction validates the supported 0..6 range.

    Precision::digits

    fn Precision::digits(self : Precision) -> Int

    Precision::new

    fn Precision::new(digits : Int) -> Result[Precision, ClipError]

    ResourceKind

    pub(all) enum ResourceKind {
    InputPaths
    InputVertices
    InternalNodes
    ScanWork
    } derive(Eq,
    Debug
    )

    SimplifyOptions

    pub(all) struct SimplifyOptions {
    epsilon : Double
    mode : PathMode
    } derive(Eq,
    Debug
    )

    SimplifyOptions::new

    fn SimplifyOptions::new(epsilon? : Double, mode? : PathMode) -> SimplifyOptions

    SimplifyResult

    pub struct SimplifyResult {
    // private fields
    } derive(
    Debug
    )

    SimplifyResult::collapsed_indices

    fn SimplifyResult::collapsed_indices(self : SimplifyResult) -> Array[Int]

    SimplifyResult::degenerate_indices

    fn SimplifyResult::degenerate_indices(self : SimplifyResult) -> Array[Int]

    SimplifyResult::input_degenerate_indices

    fn SimplifyResult::input_degenerate_indices(self : SimplifyResult) -> Array[Int]

    SimplifyResult::paths

    SimplifyResult::removed_per_path

    fn SimplifyResult::removed_per_path(self : SimplifyResult) -> Array[Int]

    SimplifyResult::removed_vertices

    fn SimplifyResult::removed_vertices(self : SimplifyResult) -> Int

    SimplifyResultD

    pub struct SimplifyResultD {
    // private fields
    } derive(
    Debug
    )

    SimplifyResultD::collapsed_indices

    fn SimplifyResultD::collapsed_indices(self : SimplifyResultD) -> Array[Int]

    SimplifyResultD::degenerate_indices

    fn SimplifyResultD::degenerate_indices(self : SimplifyResultD) -> Array[Int]

    SimplifyResultD::input_degenerate_indices

    fn SimplifyResultD::input_degenerate_indices(self : SimplifyResultD) -> Array[Int]

    SimplifyResultD::paths

    SimplifyResultD::removed_per_path

    fn SimplifyResultD::removed_per_path(self : SimplifyResultD) -> Array[Int]

    SimplifyResultD::removed_vertices

    fn SimplifyResultD::removed_vertices(self : SimplifyResultD) -> Int

    Stage

    pub(all) enum Stage {
    ValidateInputs
    Cross
    Orientation
    Bounds
    Area2
    PointOnSegment
    PointInPolygon
    NormalizePath
    NormalizePaths
    EnginePrepare
    ScanEvents
    ActiveEdges
    ScanBand
    ScanTop
    Intersections
    HorizontalEvents
    OutputTopology
    BooleanOp
    PolyTree
    PolyTreeQuery
    OffsetParameters
    OffsetGenerate
    OffsetCleanup
    StrokeParameters
    StrokeGenerate
    StrokeCleanup
    DecimalParameters
    DecimalQuantize
    DecimalOutput
    SimplifyParameters
    SimplifyEvaluate
    SimplifyReport
    SimplifyOutput
    MinkowskiParameters
    MinkowskiGenerate
    MinkowskiCleanup
    RectClipParameters
    RectClipEvaluate
    RectClipOutput
    LineClipParameters
    LineClipEvaluate
    LineClipOutput
    } derive(Eq,
    Debug
    )

    TreePointLocation64

    pub(all) enum TreePointLocation64 {
    Outside
    Inside(PolyNode64)
    InHole(PolyNode64)
    OnBoundary(Array[PolyNode64])
    }

    TreePointLocationD

    pub(all) enum TreePointLocationD {
    Outside
    Inside(PolyNodeD)
    InHole(PolyNodeD)
    OnBoundary(Array[PolyNodeD])
    }

    COORDINATE_LIMIT

    let COORDINATE_LIMIT : Int64

    Inclusive coordinate limit for geometry, not Point64 storage.

    area2

    fn area2(path : Array[Point64], limits? : Limits) -> Result[
    BigInt
    , ClipError]

    Exact twice signed area; closes the last edge implicitly. Zero area is not a validity test for self-intersecting or degenerate contours.

    boolean_op

    fn boolean_op(subject : Array[Array[Point64]], clip : Array[Array[Point64]], operation : ClipType, fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Closed paths, independent operand filling; fixed preserve_collinear=false, reverse_solution=false. Difference is Subject minus Clip.

    boolean_op_d

    fn boolean_op_d(subject : Array[Array[PointD]], clip : Array[Array[PointD]], operation : ClipType, precision? : Precision, fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    boolean_tree

    fn boolean_tree(subject : Array[Array[Point64]], clip : Array[Array[Point64]], operation : ClipType, fill_rule? : FillRule, limits? : Limits) -> Result[PolyTree64, ClipError]

    Closed integer Boolean result with geometric parentage. Empty is Ok(empty).

    boolean_tree_d

    fn boolean_tree_d(subject : Array[Array[PointD]], clip : Array[Array[PointD]], operation : ClipType, precision? : Precision, fill_rule? : FillRule, limits? : Limits) -> Result[PolyTreeD, ClipError]

    Boolean hierarchy of the quantized region, with decoded Double contours. Introduced in 0.2.0; not included in the published 0.1.0 package.

    bounds

    fn bounds(path : Array[Point64], limits? : Limits) -> Result[Bounds64?, ClipError]

    copy_path

    fn copy_path(path : Array[Point64]) -> Array[Point64]

    Copy the point array. Immutable points may be shared safely. Time and additional space are O(number of vertices).

    copy_path_d

    fn copy_path_d(path : Array[PointD]) -> Array[PointD]

    copy_paths

    fn copy_paths(paths : Array[Array[Point64]]) -> Array[Array[Point64]]

    Copy the outer array and each path separately, even for aliased input paths. Time and additional space are O(number of paths + total number of vertices).

    copy_paths_d

    fn copy_paths_d(paths : Array[Array[PointD]]) -> Array[Array[PointD]]

    cross

    fn cross(a : Point64, b : Point64, c : Point64, limits? : Limits) -> Result[Int64, ClipError]

    difference_polylines

    fn difference_polylines(paths : Array[Array[Point64]], clip : Array[Array[Point64]], fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Since 0.4.0: subtract a closed filled region from independent open integer routes. Keeps exterior intervals, including holes; removes interior and boundary overlaps. Cut endpoints may lie on the boundary. Preserves route order and ordinary vertices.

    difference_polylines_d

    fn difference_polylines_d(paths : Array[Array[PointD]], clip : Array[Array[PointD]], precision? : Precision, fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    Since 0.4.0: subtract a closed filled region from open decimal routes on one grid. Both operands share quantization; only clip contours require closed validity. Removes interior and boundary-overlap intervals; cut endpoints may lie on boundaries.

    intersect_polylines

    fn intersect_polylines(paths : Array[Array[Point64]], clip : Array[Array[Point64]], fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Since 0.4.0: intersect independent open integer routes with a closed filled region. Includes final-region boundaries; preserves route order and ordinary input vertices. Exact rational events round half away from zero, unlike rect_clip_lines truncation.

    intersect_polylines_d

    fn intersect_polylines_d(paths : Array[Array[PointD]], clip : Array[Array[PointD]], precision? : Precision, fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    Since 0.4.0: intersect open decimal routes with a closed region on one grid. Only clip contours require closed validity; both operands share collision checks. Exact integer events include region boundaries and round half away from zero.

    minkowski_sum

    fn minkowski_sum(pattern : Array[Point64], path : Array[Point64], path_is_closed : Bool, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Fixed single-pattern path sweep. No endpoint pattern fill; preserves output collinearity.

    minkowski_sum_d

    fn minkowski_sum_d(pattern : Array[PointD], path : Array[PointD], path_is_closed : Bool, precision? : Precision, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    Since 0.3.0: quantize pattern offsets and route on one grid before integer sums. Preserves the integer sweep's anchor, closure and collinear-output rules.

    minkowski_sum_tree

    fn minkowski_sum_tree(pattern : Array[Point64], path : Array[Point64], path_is_closed : Bool, limits? : Limits) -> Result[PolyTree64, ClipError]

    Since 0.3.0: hierarchy of the final sweep Union, preserving collinear vertices. Pattern offsets and route closure follow minkowski_sum; no endpoint or interior fill.

    minkowski_sum_tree_d

    fn minkowski_sum_tree_d(pattern : Array[PointD], path : Array[PointD], path_is_closed : Bool, precision? : Precision, limits? : Limits) -> Result[PolyTreeD, ClipError]

    Since 0.3.0: quantize both inputs together, then decode the same sweep hierarchy. Preserves collinear output; generation, tree construction and decoding share a budget.

    normalize_path

    fn normalize_path(path : Array[Point64], mode : PathMode, limits? : Limits) -> Result[Array[Point64], ClipError]

    normalize_paths

    fn normalize_paths(paths : Array[Array[Point64]], mode : PathMode, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Validate all original paths and vertices before allocating any output. Empty contours and original contour indices are retained.

    offset_polygons

    fn offset_polygons(paths : Array[Array[Point64]], delta : Double, fill_rule? : FillRule, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Closed filled-region offset. Normalize all inputs together before offsetting. NonZero by default; positive delta expands outers and shrinks holes.

    offset_polygons_d

    fn offset_polygons_d(paths : Array[Array[PointD]], delta : Double, precision? : Precision, fill_rule? : FillRule, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    offset_tree

    fn offset_tree(paths : Array[Array[Point64]], delta : Double, fill_rule? : FillRule, options? : OffsetOptions, limits? : Limits) -> Result[PolyTree64, ClipError]

    Final offset region with geometric parentage. Introduced in 0.2.0.

    offset_tree_d

    fn offset_tree_d(paths : Array[Array[PointD]], delta : Double, precision? : Precision, fill_rule? : FillRule, options? : OffsetOptions, limits? : Limits) -> Result[PolyTreeD, ClipError]

    Offset hierarchy on the decimal grid. Introduced in 0.2.0.

    orientation

    fn orientation(a : Point64, b : Point64, c : Point64, limits? : Limits) -> Result[Orientation, ClipError]

    Mathematical axes: x right, y up; positive cross is counterclockwise.

    point_in_polygon

    fn point_in_polygon(point : Point64, path : Array[Point64], limits? : Limits) -> Result[PointLocation, ClipError]

    Single closed contour, EvenOdd rule. Half-open y intervals count a shared vertex once; horizontal edges participate only in the boundary check.

    point_on_segment

    fn point_on_segment(point : Point64, a : Point64, b : Point64, limits? : Limits) -> Result[Bool, ClipError]

    rect_clip_lines

    fn rect_clip_lines(rect : Bounds64, paths : Array[Array[Point64]], limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Clip open integer routes to an axis-aligned window. Preserves fragment order, direction and collinear vertices; no implicit closing edge or fill semantics. Since 0.3.0. Intersections follow the pinned low-precision C++ truncation rule.

    rect_clip_lines_d

    fn rect_clip_lines_d(rect : BoundsD, paths : Array[Array[PointD]], precision? : Precision, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    Since 0.3.0: clip independent decimal open routes on a common precision grid. Preserves integer clipping's fragment order, direction and collinear vertices.

    rect_clip_polygons

    fn rect_clip_polygons(rect : Bounds64, paths : Array[Array[Point64]], fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Since 0.3.0: intersect a closed integer region with an axis-aligned window. Uses Boolean filling and grid rules; only caller paths count toward input limits.

    rect_clip_polygons_d

    fn rect_clip_polygons_d(rect : BoundsD, paths : Array[Array[PointD]], precision? : Precision, fill_rule? : FillRule, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    Since 0.3.0: clip a decimal closed region using one precision grid and budget. Window parameters do not consume raw path quotas or join the collision map.

    rect_clip_polygons_tree

    fn rect_clip_polygons_tree(rect : Bounds64, paths : Array[Array[Point64]], fill_rule? : FillRule, limits? : Limits) -> Result[PolyTree64, ClipError]

    Since 0.3.0: hierarchy of the region after window intersection, built in one scan. A hole cut open by the window becomes part of the outer contour.

    rect_clip_polygons_tree_d

    fn rect_clip_polygons_tree_d(rect : BoundsD, paths : Array[Array[PointD]], precision? : Precision, fill_rule? : FillRule, limits? : Limits) -> Result[PolyTreeD, ClipError]

    Since 0.3.0: clip on one decimal grid and decode the resulting integer hierarchy. Window, intersection, tree construction and conversion share one budget.

    simplify_paths

    fn simplify_paths(paths : Array[Array[Point64]], options? : SimplifyOptions, limits? : Limits) -> Result[SimplifyResult, ClipError]

    simplify_paths_d

    fn simplify_paths_d(paths : Array[Array[PointD]], precision? : Precision, options? : SimplifyOptions, limits? : Limits) -> Result[SimplifyResultD, ClipError]

    stroke_closed_polyline

    fn stroke_closed_polyline(path : Array[Point64], width : Double, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Since 0.4.0: widen one implicitly closed integer centerline, with no end caps. Width is full width; all vertices, including the seam, use the chosen join. Returns cleaned coverage, possibly with holes; does not fill the centerline interior.

    stroke_closed_polyline_d

    fn stroke_closed_polyline_d(path : Array[PointD], width : Double, precision? : Precision, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    Since 0.4.0: widen an implicitly closed decimal centerline with joins, no caps. Quantization skips filled-region validity; width and ArcTolerance use original units. Integer periodic generation and output decoding share the same call budget.

    stroke_closed_tree

    fn stroke_closed_tree(path : Array[Point64], width : Double, options? : OffsetOptions, limits? : Limits) -> Result[PolyTree64, ClipError]

    Since 0.4.0: hierarchy of closed-centerline coverage, built during final cleanup. Width is full width; there are joins but no caps. Roots and holes describe coverage.

    stroke_closed_tree_d

    fn stroke_closed_tree_d(path : Array[PointD], width : Double, precision? : Precision, options? : OffsetOptions, limits? : Limits) -> Result[PolyTreeD, ClipError]

    Since 0.4.0: closed-centerline coverage hierarchy on the shared decimal grid. Integer tree construction and decimal conversion run inside final scan cleanup. Query methods use this tree's original Precision; no caps or filled-input checks.

    stroke_polyline

    fn stroke_polyline(path : Array[Point64], width : Double, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Stroke a single open route with full width, two sides at width / 2. Width below 1 and routes with fewer than two effective points produce no area.

    stroke_polyline_d

    fn stroke_polyline_d(path : Array[PointD], width : Double, precision? : Precision, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    stroke_polylines

    fn stroke_polylines(paths : Array[Array[Point64]], width : Double, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[Point64]], ClipError]

    Stroke independent open routes with one shared style and full width. Since 0.3.0: all generated regions are merged in one cleanup with a shared budget.

    stroke_polylines_d

    fn stroke_polylines_d(paths : Array[Array[PointD]], width : Double, precision? : Precision, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[Array[Array[PointD]], ClipError]

    Since 0.3.0: quantize all open routes on one grid, then merge their strokes once. Width and ArcTolerance use original units; every phase shares one budget.

    stroke_polylines_tree

    fn stroke_polylines_tree(paths : Array[Array[Point64]], width : Double, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[PolyTree64, ClipError]

    Since 0.3.0: final merged hierarchy of independent open routes with one shared style.

    stroke_polylines_tree_d

    fn stroke_polylines_tree_d(paths : Array[Array[PointD]], width : Double, precision? : Precision, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[PolyTreeD, ClipError]

    Since 0.3.0: shared-grid batch stroke hierarchy; conversion stays inside scan cleanup.

    stroke_tree

    fn stroke_tree(path : Array[Point64], width : Double, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[PolyTree64, ClipError]

    Final filled hierarchy of a single open route. Introduced in 0.2.0.

    stroke_tree_d

    fn stroke_tree_d(path : Array[PointD], width : Double, precision? : Precision, cap? : CapType, options? : OffsetOptions, limits? : Limits) -> Result[PolyTreeD, ClipError]

    Open-route stroke hierarchy on the decimal grid. Introduced in 0.2.0.

    validate_paths

    fn validate_paths(paths : Array[Array[Point64]], limits? : Limits) -> Result[Unit, ClipError]

    Validate raw inputs without copying or normalizing them.