Pascal Editor吸附系统解析:网格吸附、墙体吸附等4种Snap策略
【免费下载链接】editorOpen-source 3D architectural editor with a local CLI, MCP tools, and practical workflows for humans and AI agents.项目地址: https://gitcode.com/GitHub_Trending/editor93/editor
Pascal Editor 是一款开源 3D 建筑编辑器,其**吸附系统(Snap)**是新手最容易忽略、却最影响出图精度的核心能力。本文将拆解它背后的 4 种吸附策略:网格吸附、角度吸附、墙体磁吸吸附和对齐线吸附,并说明它们如何按操作场景自动切换,帮你快速画出一丝不苟的建筑平面。
一、什么是吸附?为什么它重要
在 3D 建筑场景中,徒手摆放家具、拉墙往往"差之毫厘、谬以千里"。Pascal Editor 的吸附系统会在你拖动或绘制时,自动把光标"贴"到最合适的位置上,并提供视觉反馈(吸附信标、对齐辅助线)。
整个吸附计算被刻意设计成纯数学函数——不依赖 React、不接触场景树,因此可以被单元测试完整覆盖。核心实现分布在两个包里:
- 通用吸附数学:packages/core/src/services/snap.ts
- 吸附模式调度:packages/editor/src/lib/snapping-mode.ts
二、4 种 Snap 策略逐个拆解
1. 网格吸附(Grid Snap):把点吸到格子交点上
这是最基础的策略:任何坐标都量化为网格步长的整数倍,保证墙体、地面、家具位置落在"看得见"的格子上。
- 默认网格步长为0.25 米(通用工具)或0.5 米(墙体工具),定义见 snap.ts#L15-L19
- 核心函数
snapScalar只有一行逻辑:四舍五入到最近的步长倍数,见 snap.ts#L24-L27 - 一个巧妙设计:步长设为
0就代表"关闭网格",所有消费方都会自动跳过,无需额外开关逻辑
适用场景:画墙、放楼板、贴地砖——任何需要"整齐"的操作。
2. 角度吸附(Angle Snap):15° 步进锁定方向
画斜墙时最怕角度"飘"。角度吸附会把光标方向锁定到15° 的整数倍(π/12),也就是常见的 15°/30°/45°/60° 等建筑常用角。
snapPointToAngle:先把角度吸附,再保留原始距离,见 snap.ts#L96-L112snapPointAlongAngleRay:角度锁定后,沿射线把距离也按网格量化,端点稳稳落在格点上- 还有一个"角度白名单"函数
snapAngleToList,可以吸附到任意自定义角度集合(默认容差 5°)
适用场景:画斜墙、定栏杆方向、布置斜向天窗——需要"方向感"的操作。
3. 墙体吸附(Wall Magnetic Snap):把端点吸到墙上
这是 Pascal Editor 的招牌能力——画第二面墙时,光标会"磁吸"到已有墙上,自动闭合房间、自动接墙脚。几何逻辑全部在 wall-snap-geometry.ts 中,按优先级从高到低依次尝试 4 类目标:
| 优先级 | 吸附目标 | 捕获半径 | 说明 |
|---|---|---|---|
| ① | 端点(endpoint) | 0.7 m | 最强意图:闭合多边形、接墙角 |
| ② | 中点(midpoint) | 0.5 m | 精确挂到墙的正中间 |
| ③ | 交点(intersection) | 0.5 m | 两条墙的理论交叉处 |
| ④ | 墙体(wall body) | 0.35 m | 吸附到墙身任意位置 |
半径常量定义见 wall-snap-geometry.ts#L36-L54。
特别值得学习的细节:特殊点吸附从原始光标而非网格预吸附后的点出发,避免"中间一次网格量化把光标推离墙角"导致漏吸;曲线墙会被离散采样后参与候选。命中后还会返回targetWallIds(来源墙 ID),供后续"拆分墙体""传递构造参数"等下游逻辑使用。
4. 对齐线吸附(Alignment Lines):Figma 式辅助线
拖动家具时,你会看到红/绿色的辅助线——这就是对齐吸附。它借鉴了 Figma 的行为,核心解析器在 packages/core/src/services/alignment.ts:
- 锚点体系:每个对象贡献 9 个标准锚点(4 角 + 4 边中点 + 中心),见
bboxAnchors函数,alignment.ts#L268-L288 - 每轴最多 1 条线:X 轴和 Z 轴各自取最近匹配,最多画 2 条辅助线,视觉信号干净不杂乱
- 墙面对齐:墙体锚点会额外偏移半个墙厚,让家具能贴到墙的面而非中心线,见 alignment-anchors.ts#L202-L231
- 楼层过滤:只会与当前楼层的对象对齐,避免和楼下同一位置的墙"隔空对齐"
三、4 种策略如何协同:按场景自动切换
Pascal Editor 的吸附不是全局开关,而是"每个操作场景有自己的模式集"。用户可以用快捷键在模式间循环切换:
| 场景 | 可选模式 | 默认模式 | 设计理由 |
|---|---|---|---|
| 画墙 / 拖墙端点 | 网格 / 线条 / 角度 / 关 | 网格 | 方向重要 → 需要角度锁定 |
| 摆放 / 移动家具 | 线条 / 网格 / 关 | 线条 | 自由移动,只在对齐线处"咬住" |
| 画楼板 / 整墙平移 | 网格 / 线条 / 关 | 网格 | 无方向可言 → 不给角度锁定 |
模式到开关的映射是"互斥"的——每种模式只启用一种吸附,HUD 显示什么就只发生什么,见 snapping-mode.ts#L34-L45 和场景配置 snapping-mode.ts#L81-L91。
还有一个兜底机制:即使选了"网格"或"角度"模式,端点在 5 cm 范围内依然会轻吸到已有墙上(WALL_CONNECT_SNAP_RADIUS = 0.05),保证房间总能闭合——精细控制与连接可靠性兼得。
四、想深入源码?从这里看起
| 模块 | 路径 | 看点 |
|---|---|---|
| 网格/角度吸附数学 | snap.ts | 纯函数、稳定契约 |
| 吸附模式调度 | snapping-mode.ts | 场景化默认值设计 |
| 墙体磁吸几何 | wall-snap-geometry.ts | 优先级与半径设计 |
| 画墙吸附入口 | wall-drafting.ts | 网格/角度/磁吸的装配顺序 |
| 对齐线解析 | alignment.ts | Figma 式双轴匹配 |
| 移动约束(轴锁+网格) | movement.ts#L51-L68 | 节点级移动约束 |
| 全局吸附状态 | use-editor.tsx#L1607-L1627 | 模式→开关的最终裁决 |
五、小结:新手如何用好吸附
- 🧱画墙→ 留在默认"网格"模式,需要斜墙时切到"角度"模式
- 🛋️摆家具→ 用默认"线条"模式,让对齐辅助线帮你贴墙、贴边
- 📐收尾检查→ 切到"网格"模式,快速量化修正微小偏移
Pascal Editor 用 4 种各司其职的 Snap 策略 + 场景化的默认值,把"像素级精确"变成了"无意识获得"。理解这套机制后,无论是手动操作还是通过本地 CLI、MCP 工具让 AI Agent 参与建模,你产出的图纸都会天然整洁。
【免费下载链接】editorOpen-source 3D architectural editor with a local CLI, MCP tools, and practical workflows for humans and AI agents.项目地址: https://gitcode.com/GitHub_Trending/editor93/editor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考