惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
Vercel News
Vercel News
N
Netflix TechBlog - Medium
M
MIT News - Artificial intelligence
F
Full Disclosure
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
Hacker News: Ask HN
Hacker News: Ask HN
V
Visual Studio Blog
IT之家
IT之家
N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
月光博客
月光博客
H
Heimdal Security Blog
T
The Blog of Author Tim Ferriss
腾讯CDC
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Troy Hunt's Blog
小众软件
小众软件
Jina AI
Jina AI
博客园 - Franky
Scott Helme
Scott Helme
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CERT Recently Published Vulnerability Notes
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
TaoSecurity Blog
TaoSecurity Blog
F
Fortinet All Blogs
Y
Y Combinator Blog
P
Privacy & Cybersecurity Law Blog
B
Blog RSS Feed
Microsoft Security Blog
Microsoft Security Blog
量子位
H
Help Net Security
MongoDB | Blog
MongoDB | Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
The Last Watchdog
The Last Watchdog
博客园 - 三生石上(FineUI控件)
L
LINUX DO - 最新话题

博客园 - 我才是银古

第16章:常见问题、排错与最佳实践 第15章:扩展生态、MCAD 与外部集成 第12章:实战案例:机械结构与 3D 打印零件 第14章:构建、测试、调试与贡献流程 第13章:OpenSCAD 源码架构与核心执行流程 第11章:预览、渲染、网格精度与性能优化 第09章:列表推导、递归与算法建模 第08章:参数化零件库与复用设计 第10章:导入导出、命令行与自动化 第06章:CSG 布尔建模方法 第07章:二维图形、拉伸、旋转与投影 第05章:基础几何、坐标系与变换 第04章:参数、变量、函数、模块与作用域 OpenSCAD 教程目录 第03章:OpenSCAD 语言基础 第02章:安装、环境配置与开发工作流 第01章:OpenSCAD 项目全景与学习路线 第02章:源码获取、编译与开发环境配置 第01章:OCCT项目全景与学习路线 第18章:二次开发实战与综合案例 第18章:综合实战案例 第17章:数据交换与协同 第16章:源码架构与二次开发 第15章:插件与自定义工作台开发 第14章:Python脚本宏与自动化 第13章:FEM仿真分析 第12章:CAM数控加工 第11章:SurfaceMesh与逆向工程 第10章:Draft二维绘图与BIM建筑 第09章:工程图TechDraw 第07章:参数化表达式与Spreadsheet 第08章:装配设计Assembly 第06章:Part工作台与几何内核 第05章:PartDesign实体特征建模 第04章:草图Sketcher约束建模 第02章:安装版本与工作环境配置 第03章:界面工作台与基础操作 第01章:项目全景与学习路线 第十二章:插件开发、研究功能与最佳实践 第十章:定时任务与自动化(Cron) 第七章:技能、记忆与自学习闭环 第八章:MCP 集成与上下文文件 第六章:工具系统与终端后端 第五章:模型供应商与配置体系 Hermes Agent 教程目录 第十一章:语音、视觉、浏览器与子代理协作 第四章:CLI/TUI 与会话管理 第十二章:学习路线、实战方案与最佳实践 第十一章:源码结构、开发调试与插件开发 第十章:自动化、远程访问、日志与排障 第九章:Control UI、节点、Canvas 与语音能力 第七章:工具、技能、插件与能力扩展 第八章:安全模型、访问控制与沙箱实践 第六章:Agent 工作区、会话与多智能体路由 第五章:多通道消息接入与聊天平台配置 第四章:配置体系、模型接入与认证管理 第三章:Gateway 架构、协议与运行机制 第二章:安装、环境准备与快速上手 第一章:OpenClaw 项目概览与核心定位 oh-my-openagent 教程目录 09-命令模型回退与配置参考 10-实战案例最佳实践与故障排除 05-工作模式-Ultrawork-Prometheus-Atlas 08-Hooks与MCP系统 06-Category与Skill系统 07-核心工具链 04-智能体全景详解 03-安装与环境配置 02-整体架构与多模型编排机制 01-项目简介与核心理念 01-项目概览与学习路线 02-安装部署与工具适配 03-Skill机制与using-superpowers 05-TDD系统化调试与完成前验证 04-需求澄清方案设计与计划编写 07-并行智能体子智能体与Git-Worktree 第六章:代码审查、反馈处理与分支收尾 08-中国特色Skills与本土团队落地 09-MCP构建工作流执行与自定义Skill 第23章:FreeCAD-Python-API Clipper2 C# 源码解读教程 第19章:PolyTree 多边形树结构 第20章:实际应用与最佳实践 第18章:Minkowski 和与差 第17章:RectClip 矩形裁剪优化 第16章:ClipperOffset 偏移类详解 第15章:填充规则详解 第14章:布尔运算执行流程 第13章:ClipperD 浮点裁剪类 第11章:OutRec 与 OutPt 输出结构 第9章:Active 活动边结构 第10章:Vertex 顶点与 LocalMinima 局部极小值 第12章:Clipper64 裁剪类详解 第7章:高精度运算与128位整数 第8章:ClipperBase 基类详解 第5章:枚举类型与常量定义 第6章:InternalClipper 内部工具类 第2章:核心数据结构 - Point64、PointD 第3章:路径与多边形表示 - Path64、PathD、Paths64、PathsD 第4章:矩形边界 - Rect64、RectD
第4章:枚举类型与常量定义
我才是银古 · 2026-06-24 · via 博客园 - 我才是银古

第4章:枚举类型与常量定义

4.1 概述

Clipper1 定义了多个枚举类型和常量,用于控制裁剪行为、指定填充规则、设置偏移选项等。理解这些定义对于正确使用 Clipper 至关重要。

4.2 ClipType 枚举

ClipType 定义了四种布尔运算类型:

public enum ClipType { 
    ctIntersection,  // 交集
    ctUnion,         // 并集
    ctDifference,    // 差集
    ctXor            // 异或
}

4.2.1 Intersection(交集)

  Subject      Clip        Result
  ┌───┐       ┌───┐       
  │ S │       │ C │         ┌─┐
  │ ┌─┼───┐   │   │    =    │█│
  └─┼─┘   │   └───┘         └─┘
    └─────┘

特点:返回两个多边形重叠的区域。

应用场景

  • 计算两个区域的公共部分
  • 遮罩/裁剪效果
  • 碰撞检测中的重叠区域

4.2.2 Union(并集)

  Subject      Clip        Result
  ┌───┐       ┌───┐       ┌───────┐
  │ S │       │ C │       │███████│
  │ ┌─┼───┐   │   │    =  │███████│
  └─┼─┘   │   └───┘       └───────┘
    └─────┘

特点:返回两个多边形覆盖的所有区域。

应用场景

  • 合并相邻区域
  • 消除内部边界
  • 构建复合形状

4.2.3 Difference(差集)

  Subject      Clip        Result
  ┌───┐       ┌───┐       ┌──┐
  │ S │       │ C │       │██│
  │ ┌─┼───┐   │   │    =  │██│
  └─┼─┘   │   └───┘       └──┘
    └─────┘

特点:返回 Subject 中不与 Clip 重叠的部分。

应用场景

  • 从形状中挖孔
  • 计算边界区域
  • 布尔减法运算

4.2.4 Xor(异或)

  Subject      Clip        Result
  ┌───┐       ┌───┐       ┌──┬──┐
  │ S │       │ C │       │██│  │
  │ ┌─┼───┐   │   │    =  │  └──┤
  └─┼─┘   │   └───┘       └────█│
    └─────┘                     │
                                └┘

特点:返回两个多边形不重叠的部分(对称差)。

应用场景

  • 检测变化区域
  • 高亮差异
  • 边界效果

4.3 PolyType 枚举

PolyType 指定多边形在布尔运算中的角色:

public enum PolyType { 
    ptSubject,  // 主体多边形
    ptClip      // 裁剪多边形
}

4.3.1 使用方式

Clipper clipper = new Clipper();

// 添加主体多边形
clipper.AddPath(subjectPath, PolyType.ptSubject, true);
clipper.AddPaths(subjectPaths, PolyType.ptSubject, true);

// 添加裁剪多边形
clipper.AddPath(clipPath, PolyType.ptClip, true);
clipper.AddPaths(clipPaths, PolyType.ptClip, true);

4.3.2 对布尔运算的影响

运算类型 Subject Clip 结果
Intersection Subject ∩ Clip
Union Subject ∪ Clip
Difference Subject - Clip
Xor Subject ⊕ Clip

注意:Difference 运算是不对称的,Subject - Clip ≠ Clip - Subject。

4.4 PolyFillType 枚举

PolyFillType 定义多边形填充规则,决定哪些区域被视为"内部":

public enum PolyFillType { 
    pftEvenOdd,   // 奇偶规则
    pftNonZero,   // 非零规则
    pftPositive,  // 正向规则
    pftNegative   // 负向规则
}

4.4.1 EvenOdd(奇偶规则)

从点发射射线,计数穿过的边数:
- 奇数:内部
- 偶数:外部

    ┌─────────────┐
    │  1(内)      │
┌───┼───┐         │
│ 2 │ 1 │         │
│(外)│(内)        │
└───┴───┴─────────┘

特点

  • 最常用的规则
  • 自动处理自相交多边形
  • 交替填充重叠区域

4.4.2 NonZero(非零规则)

从点发射射线:
- 向上穿过:winding_number++
- 向下穿过:winding_number--
- winding_number ≠ 0:内部
- winding_number = 0:外部

    →→→→→→→→→→→→→→
    ┌─────────────┐
    │ winding=1   │
    │    (内)     │
    ↓   ┌───┐     ↑
    │   │w=2│     │
    │   │(内)     │
    └───┴───┴─────┘

特点

  • 考虑边的方向
  • 同向重叠区域保持填充
  • 适合路径描边

4.4.3 Positive(正向规则)

// 只有 winding_number > 0 的区域被填充

特点

  • 只填充正向缠绕的区域
  • 忽略负向边的贡献

4.4.4 Negative(负向规则)

// 只有 winding_number < 0 的区域被填充

特点

  • 只填充负向缠绕的区域
  • 忽略正向边的贡献

4.4.5 填充规则对比

// 自相交多边形(8字形)
Path figure8 = new Path();
figure8.Add(new IntPoint(0, 0));
figure8.Add(new IntPoint(100, 100));
figure8.Add(new IntPoint(100, 0));
figure8.Add(new IntPoint(0, 100));

// 使用不同填充规则
Paths resultEvenOdd = new Paths();
Paths resultNonZero = new Paths();

clipper.AddPath(figure8, PolyType.ptSubject, true);
clipper.Execute(ClipType.ctUnion, resultEvenOdd, 
    PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);

clipper.Clear();
clipper.AddPath(figure8, PolyType.ptSubject, true);
clipper.Execute(ClipType.ctUnion, resultNonZero, 
    PolyFillType.pftNonZero, PolyFillType.pftNonZero);

4.5 JoinType 枚举

JoinType 用于 ClipperOffset,指定偏移时拐角的连接方式:

public enum JoinType { 
    jtSquare,  // 方形连接
    jtRound,   // 圆形连接
    jtMiter    // 斜接连接
}

4.5.1 Square(方形连接)

原始角:      偏移后:
    ╱          ┌───┐
   ╱           │   │
  ╱            │   │

特点

  • 在拐角处创建 45° 斜切
  • 产生明确的边界
  • 适合工程应用

4.5.2 Round(圆形连接)

原始角:      偏移后:
    ╱          ╭───╮
   ╱           │   │
  ╱            │   │

特点

  • 在拐角处创建圆弧
  • 视觉效果平滑
  • 适合图形设计

4.5.3 Miter(斜接连接)

原始角:      偏移后:
    ╱             ╱
   ╱           ╱
  ╱          ╱
           ╱

特点

  • 延伸边线直到相交
  • 锐角可能产生很长的尖角
  • 使用 MiterLimit 控制最大延伸

4.6 EndType 枚举

EndType 用于 ClipperOffset,指定开放路径端点的处理方式:

public enum EndType { 
    etClosedPolygon,  // 闭合多边形
    etClosedLine,     // 闭合线
    etOpenButt,       // 开放-平头
    etOpenSquare,     // 开放-方头
    etOpenRound       // 开放-圆头
}

4.6.1 ClosedPolygon

// 用于闭合多边形,首尾自动连接
// 偏移会产生内外两个轮廓(或只有外轮廓)

4.6.2 ClosedLine

// 用于闭合线(首尾连接但可能自相交)
// 偏移两侧但不在端点处闭合

4.6.3 OpenButt(平头)

原始线:        偏移后:
───────        ┌───────┐
               └───────┘

4.6.4 OpenSquare(方头)

原始线:        偏移后:
───────       ┌─────────┐
              └─────────┘
              (延伸 delta 距离)

4.6.5 OpenRound(圆头)

原始线:        偏移后:
───────       ╭─────────╮
              ╰─────────╯
              (圆弧端点)

4.7 内部枚举类型

4.7.1 EdgeSide

internal enum EdgeSide { esLeft, esRight }

指定边相对于输出多边形的位置(左侧或右侧)。

4.7.2 Direction

internal enum Direction { dRightToLeft, dLeftToRight }

指定边的扫描方向,用于水平边处理。

4.8 常量定义

4.8.1 ClipperBase 常量

public class ClipperBase
{    
    internal const double horizontal = -3.4E+38;
    internal const int Skip = -2;
    internal const int Unassigned = -1;
    internal const double tolerance = 1.0E-20;
    
    internal static bool near_zero(double val)
    {
        return (val > -tolerance) && (val < tolerance);
    }

#if use_int32
    public const cInt loRange = 0x7FFF;
    public const cInt hiRange = 0x7FFF;
#else
    public const cInt loRange = 0x3FFFFFFF;
    public const cInt hiRange = 0x3FFFFFFFFFFFFFFFL; 
#endif
}
常量 说明
horizontal -3.4E+38 标识水平边的特殊斜率值
Skip -2 标记需要跳过的边
Unassigned -1 表示未分配的输出索引
tolerance 1.0E-20 浮点数零判断的容差
loRange 0x3FFFFFFF 低精度模式的坐标范围
hiRange 0x3FFFFFFFFFFFFFFFL 高精度模式的坐标范围

4.8.2 Clipper 常量

public class Clipper : ClipperBase
{
    // InitOptions 可以传递给构造函数
    public const int ioReverseSolution = 1;
    public const int ioStrictlySimple = 2;
    public const int ioPreserveCollinear = 4;
}
常量 说明
ioReverseSolution 1 反转结果多边形的方向
ioStrictlySimple 2 确保结果是严格简单的多边形
ioPreserveCollinear 4 保留共线顶点

4.8.3 使用 InitOptions

// 默认选项
Clipper clipper1 = new Clipper();

// 反转结果方向
Clipper clipper2 = new Clipper(Clipper.ioReverseSolution);

// 严格简单多边形
Clipper clipper3 = new Clipper(Clipper.ioStrictlySimple);

// 组合选项(使用位或)
Clipper clipper4 = new Clipper(
    Clipper.ioReverseSolution | Clipper.ioStrictlySimple
);

// 也可以通过属性设置
clipper1.ReverseSolution = true;
clipper1.StrictlySimple = true;
clipper1.PreserveCollinear = true;

4.8.4 ClipperOffset 常量

public class ClipperOffset
{
    private const double two_pi = Math.PI * 2;
    private const double def_arc_tolerance = 0.25;
    
    public double ArcTolerance { get; set; }
    public double MiterLimit { get; set; }
}
常量/属性 默认值 说明
two_pi 完整圆的弧度
def_arc_tolerance 0.25 默认弧度容差
ArcTolerance 0.25 圆弧近似的容差
MiterLimit 2.0 斜接限制

4.9 横向边斜率常量

internal const double horizontal = -3.4E+38;

这个特殊值用于标识水平边。在 Clipper 的坐标系中(Y 轴向上),水平边的斜率定义为无穷大或极大值。使用 -3.4E+38 而非正无穷,是为了便于比较和特殊处理。

使用示例

internal static bool IsHorizontal(TEdge e)
{
    return e.Delta.Y == 0;
}

private void SetDx(TEdge e)
{
    e.Delta.X = (e.Top.X - e.Bot.X);
    e.Delta.Y = (e.Top.Y - e.Bot.Y);
    if (e.Delta.Y == 0) 
        e.Dx = horizontal;
    else 
        e.Dx = (double)(e.Delta.X) / (e.Delta.Y);
}

4.10 坐标范围常量详解

4.10.1 32位模式

#if use_int32
    public const cInt loRange = 0x7FFF;     // 32,767
    public const cInt hiRange = 0x7FFF;     // 32,767
#endif

在 32 位模式下,坐标范围被严格限制,因为中间计算可能产生溢出。

4.10.2 64位模式

#else
    public const cInt loRange = 0x3FFFFFFF;           // 约 10⁹
    public const cInt hiRange = 0x3FFFFFFFFFFFFFFFL; // 约 4.6×10¹⁸
#endif

两个范围的意义

  • loRange:低精度范围,中间计算使用普通 64 位整数
  • hiRange:高精度范围,中间计算使用 128 位整数(Int128)

当坐标超过 loRange 时,Clipper 自动切换到 128 位计算模式,以避免溢出。

4.11 本章小结

本章详细介绍了 Clipper1 中的枚举类型和常量:

  1. 布尔运算类型(ClipType)

    • 交集、并集、差集、异或
  2. 多边形类型(PolyType)

    • 主体和裁剪多边形的区分
  3. 填充规则(PolyFillType)

    • 奇偶、非零、正向、负向规则
  4. 偏移选项

    • JoinType:方形、圆形、斜接连接
    • EndType:各种端点处理方式
  5. 重要常量

    • 坐标范围限制
    • 初始化选项
    • 特殊标记值

理解这些枚举和常量是正确配置 Clipper 的基础,不同的选项组合可以实现各种复杂的几何运算需求。


上一章:路径与多边形表示 | 返回目录 | 下一章:Int128高精度运算