UCS(用户坐标系)体系设计分析
摘要:在 CAD 制图中,世界坐标系(WCS)难以直接支撑斜视图、局部斜坐标与任意方向制图。既有系统仅以 Plane {XY, YZ, XZ} 表示三投影面,且该枚举仅用于状态显示,完全不参与坐标换算,导致全代码库隐式假设坐标系恒为世界 XY。本文提出一套静态命名 UCS(用户坐标系)体系,将 UCS 形式化为二维刚性变换群 SE(2)SE(2)SE(2) 的子集,由原点 ooo 与绕 ZZZ 轴旋转角 θ\\thetaθ 唯一确定。设计遵循“插入层 = 输入/显示层,绝不碰存储层”的铁律,使 Element.pts 始终保存世界坐标,存档格式零改动。通过单一换算入口 SketchModel::toWorld()/toUcs() 收口所有坐标变换,并在 Snap、GraphicsView、命令解析、状态栏等模块按 UCS 轴对齐,同时保持约束求解器以世界系为唯一基准。新增 t_ucs 自测 24 条 CHECK,覆盖数学恒等、命令定义、极轴/正交/栅格、读数切换与不入档断言。全量自测零回归。本文进一步给出动态 UCS 的扩展路径、零回归设计模式与架构决策的形式化论证。
关键词:用户坐标系;UCS;二维刚性变换;世界坐标;坐标换算;零回归;CAD 制图;动态 UCS
0 引言
在计算机辅助设计(CAD)中,世界坐标系(World Coordinate System, WCS)为所有几何对象提供全局基准。然而,实际制图常需在斜视图、局部斜坐标或任意方向工作面上操作。若系统仅支持世界 XY 平面,用户不得不通过繁琐的坐标心算或辅助线完成斜向绘制,效率低且易错。
用户坐标系(User Coordinate System, UCS)允许用户定义局部原点与旋转方向,使输入、显示、捕捉、极轴、正交与读数均以局部系为基准,而底层存储仍保持世界坐标。这一“输入/显示变换、存储不变”的架构,既能满足斜向制图需求,又能保证存档兼容与既有算法无感。
本文对既有代码进行彻底勘察,发现三个关键问题:
本文的核心设计思想是:
将 UCS 建模为二维刚性变换,插入到输入/显示边界,存储层始终为世界坐标。
形式化地,设世界坐标为 pw∈R2p_w \\in \\mathbb{R}^2pw∈R2,UCS 局部坐标为 pu∈R2p_u \\in \\mathbb{R}^2pu∈R2,UCS 由原点 o∈R2o \\in \\mathbb{R}^2o∈R2 与旋转角 θ∈[0,2π)\\theta \\in [0, 2\\pi)θ∈[0,2π) 定义。则正变换 Tu→wT_{u \\to w}Tu→w 与逆变换 Tw→uT_{w \\to u}Tw→u 为:
pw=Tu→w(pu)=o+R(θ)pu
p_w = T_{u \\to w}(p_u) = o + R(\\theta) p_u
pw=Tu→w(pu)=o+R(θ)pu
pu=Tw→u(pw)=R(−θ)(pw−o)
p_u = T_{w \\to u}(p_w) = R(-\\theta)(p_w – o)
pu=Tw→u(pw)=R(−θ)(pw−o)
其中旋转矩阵:
R(θ)=(cosθ−sinθsinθcosθ)
R(\\theta) =
\\begin{pmatrix}
\\cos\\theta & -\\sin\\theta \\\\
\\sin\\theta & \\cos\\theta
\\end{pmatrix}
R(θ)=(cosθsinθ−sinθcosθ)
满足正交性:
R(θ)⊤R(θ)=I,R(θ)−1=R(θ)⊤=R(−θ)
R(\\theta)^\\top R(\\theta) = I,\\qquad
R(\\theta)^{-1} = R(\\theta)^\\top = R(-\\theta)
R(θ)⊤R(θ)=I,R(θ)−1=R(θ)⊤=R(−θ)
因此往返变换恒等:
Tw→u(Tu→w(pu))=pu
T_{w \\to u}(T_{u \\to w}(p_u)) = p_u
Tw→u(Tu→w(pu))=pu
误差仅来自浮点舍入,自测要求 ≤10−9\\le 10^{-9}≤10−9。
本文贡献如下:
1 现状勘察与问题定义
1.1 Plane 空头机制
既有代码中:
enum class Plane { XY, YZ, XZ };
SketchModel::plane_ 仅用于状态栏或 HUD 显示,不参与任何坐标换算。所有几何算法、渲染、捕捉、约束求解均隐式假设世界 XY 平面。因此,plane 命令虽可切换显示,但不会改变实际坐标语义。
1.2 无集中坐标换算入口
点解析 CommandContext::tryParsePoint 仅支持绝对 x,y[,z],不支持:
- @dx,dy 相对笛卡尔坐标;
- dist<angle 绝对极坐标;
- @dist<angle 相对极坐标。
DYN 动态输入 commitDynInput 直接对世界 X 轴计算:
Δp=ℓ⋅(cosα,sinα)
\\Delta p = \\ell \\cdot (\\cos\\alpha, \\sin\\alpha)
Δp=ℓ⋅(cosα,sinα)
未考虑 UCS 旋转。
1.3 硬编码世界轴
| Snap.cpp | OTRACK/TK 对齐硬编码 (1,0,0) / (0,1,0) | 斜向追踪失效 |
| Snap.cpp | 正交分解与极轴角基准以世界 X 为 0∘0^\\circ0∘ | 极轴方向错误 |
| GraphicsView.cpp | 网格、坐标轴图标、极轴射线、正交引导线、HUD、坐标读数 | 显示与 UCS 不一致 |
| ConstraintSolver | 角度约束以世界 X 为 0∘0^\\circ0∘ | 约束语义固定于世界系 |
1.4 问题形式化
设真实存储坐标为 pstorep_{\\text{store}}pstore,用户输入坐标为 pinp_{\\text{in}}pin,显示坐标为 pdispp_{\\text{disp}}pdisp。理想 UCS 体系应满足:
pstore=Tu→w(pin)
p_{\\text{store}} = T_{u \\to w}(p_{\\text{in}})
pstore=Tu→w(pin)
pdisp=Tw→u(pstore)
p_{\\text{disp}} = T_{w \\to u}(p_{\\text{store}})
pdisp=Tw→u(pstore)
且存档格式不变:
JSONnew=JSONold
\\mathrm{JSON}_{\\text{new}} = \\mathrm{JSON}_{\\text{old}}
JSONnew=JSONold
在顶层键集上完全一致。既有系统因缺少统一 TTT,导致输入、显示、捕捉各自为政,斜向制图无法正确工作。
2 核心设计决策
2.1 UCS = 二维刚性变换
定义 UCS 结构:
struct Ucs {
QString name;
Vec3 origin; // 原点(世界坐标)
double angleRad; // 绕 Z 轴旋转角
};
派生轴向量:
xaxis=(cosθ,sinθ,0)
x_{\\text{axis}} = (\\cos\\theta, \\sin\\theta, 0)
xaxis=(cosθ,sinθ,0)
yaxis=(−sinθ,cosθ,0)
y_{\\text{axis}} = (-\\sin\\theta, \\cos\\theta, 0)
yaxis=(−sinθ,cosθ,0)
二者单位正交,且 zzz 分量直通,不改变 Z 语义。正逆变换:
pw=o+R(θ)pu
p_w = o + R(\\theta) p_u
pw=o+R(θ)pu
pu=R(−θ)(pw−o)
p_u = R(-\\theta)(p_w – o)
pu=R(−θ)(pw−o)
默认 UCS = 世界系:
o=(0,0,0),θ=0
o = (0,0,0),\\qquad \\theta = 0
o=(0,0,0),θ=0
此时:
R(0)=I,Tu→w=Tw→u=id
R(0) = I,\\qquad T_{u \\to w} = T_{w \\to u} = \\mathrm{id}
R(0)=I,Tu→w=Tw→u=id
既有 963 条自测零回归。
旋转矩阵正交可逆,因此:
Tw→u(Tu→w(p))=p
T_{w \\to u}(T_{u \\to w}(p)) = p
Tw→u(Tu→w(p))=p
自测覆盖往返误差 ≤10−9\\le 10^{-9}≤10−9。
2.2 插入层 = 输入/显示层,绝不碰存储层
铁律:Element.pts 始终是世界坐标。
UCS 只存在于两道转换边界上:
用户输入(命令行/DYN/鼠标)──toWorld──▶ 世界坐标 ──▶ Element.pts(存储,不变)
Element.pts(世界)──toUcs──▶ 显示(网格/极轴/读数/HUD)
由此保证:
- 存档格式零改动,旧档/新档完全兼容;
- 既有渲染、导出、约束求解全部无感;
- 几何算法不感知 UCS,避免大规模回归。
2.3 世界 ↔ 用户换算收口到唯一入口
SketchModel::toWorld() / toUcs() 是唯一换算入口,内联转发 currentUcs_。所有输入与显示路径均消费它,杜绝“同一处换算散落多处导致方向不一致”。
形式化地,令所有输入路径集合为 Pin\\mathcal{P}_{\\text{in}}Pin,显示路径集合为 Pdisp\\mathcal{P}_{\\text{disp}}Pdisp,则:
∀p∈Pin,pw=SketchModel::toWorld(p)
\\forall p \\in \\mathcal{P}_{\\text{in}},\\quad p_w = \\mathrm{SketchModel::toWorld}(p)
∀p∈Pin,pw=SketchModel::toWorld(p)
∀p∈Pdisp,pu=SketchModel::toUcs(p)
\\forall p \\in \\mathcal{P}_{\\text{disp}},\\quad p_u = \\mathrm{SketchModel::toUcs}(p)
∀p∈Pdisp,pu=SketchModel::toUcs(p)
不存在旁路。
2.4 命名 UCS 表不序列化
ucsTable_ 存内存(QMap),不入 toDrawingJson / Memento。理由:
该决策可形式化为:
Keys(JSONnew)=Keys(JSONold)
\\mathrm{Keys}(\\mathrm{JSON}_{\\text{new}}) = \\mathrm{Keys}(\\mathrm{JSON}_{\\text{old}})
Keys(JSONnew)=Keys(JSONold)
且:
"ucs"∉Keys(JSONnew)
\\texttt{"ucs"} \\notin \\mathrm{Keys}(\\mathrm{JSON}_{\\text{new}})
"ucs"∈/Keys(JSONnew)
"ucsTable"∉Keys(JSONnew)
\\texttt{"ucsTable"} \\notin \\mathrm{Keys}(\\mathrm{JSON}_{\\text{new}})
"ucsTable"∈/Keys(JSONnew)
2.5 plane 命令原样保留
既有 plane xy|yz|xz 三态行为不变。UCS 与 Plane 是并行概念,状态栏同时呈现:
平面:XY
⌖ WCS/UCS名 角度°
3 数学原理与公式
3.1 二维刚性变换群
二维刚性变换群 SE(2)SE(2)SE(2) 元素可表示为:
T(o,θ)=(R(θ)o0⊤1)
T(o,\\theta) =
\\begin{pmatrix}
R(\\theta) & o \\\\
0^\\top & 1
\\end{pmatrix}
T(o,θ)=(R(θ)0⊤o1)
其中 o∈R2o \\in \\mathbb{R}^2o∈R2,R(θ)∈SO(2)R(\\theta) \\in SO(2)R(θ)∈SO(2)。本文 UCS 即为 SE(2)SE(2)SE(2) 的子集,但限制 zzz 分量直通,且仅绕 ZZZ 轴旋转。
3.2 正逆变换
正变换:
pw=o+R(θ)pu
p_w = o + R(\\theta) p_u
pw=o+R(θ)pu
逆变换:
pu=R(−θ)(pw−o)
p_u = R(-\\theta)(p_w – o)
pu=R(−θ)(pw−o)
展开为分量形式:
$$
\\begin{pmatrix} x_w \\ y_w \\end{pmatrix}
\\begin{pmatrix} x_o \\ y_o \\end{pmatrix}
+
\\begin{pmatrix}
\\cos\\theta & -\\sin\\theta \\
\\sin\\theta & \\cos\\theta
\\end{pmatrix}
\\begin{pmatrix} x_u \\ y_u \\end{pmatrix}
$$
$$
\\begin{pmatrix} x_u \\ y_u \\end{pmatrix}
\\begin{pmatrix}
\\cos\\theta & \\sin\\theta \\
-\\sin\\theta & \\cos\\theta
\\end{pmatrix}
\\begin{pmatrix} x_w – x_o \\ y_w – y_o \\end{pmatrix}
$$
3.3 正交性与往返恒等
旋转矩阵满足:
R(θ)⊤R(θ)=I
R(\\theta)^\\top R(\\theta) = I
R(θ)⊤R(θ)=I
detR(θ)=1
\\det R(\\theta) = 1
detR(θ)=1
因此:
R(θ)−1=R(θ)⊤=R(−θ)
R(\\theta)^{-1} = R(\\theta)^\\top = R(-\\theta)
R(θ)−1=R(θ)⊤=R(−θ)
往返恒等:
Tw→u(Tu→w(pu))=R(−θ)(o+R(θ)pu−o)=pu
T_{w \\to u}(T_{u \\to w}(p_u)) = R(-\\theta)(o + R(\\theta)p_u – o) = p_u
Tw→u(Tu→w(pu))=R(−θ)(o+R(θ)pu−o)=pu
3.4 极坐标与相对坐标
绝对极坐标:
pu=o+d⋅(cos(α+θ),sin(α+θ))
p_u = o + d \\cdot (\\cos(\\alpha + \\theta), \\sin(\\alpha + \\theta))
pu=o+d⋅(cos(α+θ),sin(α+θ))
其中 ddd 为距离,α\\alphaα 为相对 UCS X 轴的角度。
相对笛卡尔:
pu=pbase,u+(Δx,Δy)
p_u = p_{\\text{base},u} + (\\Delta x, \\Delta y)
pu=pbase,u+(Δx,Δy)
相对极坐标:
pu=pbase,u+d⋅(cos(α+θ),sin(α+θ))
p_u = p_{\\text{base},u} + d \\cdot (\\cos(\\alpha + \\theta), \\sin(\\alpha + \\theta))
pu=pbase,u+d⋅(cos(α+θ),sin(α+θ))
3.5 误差界
浮点往返误差主要来自矩阵乘法与加减。设机器精度为 εm\\varepsilon_mεm,则:
∥Tw→u(Tu→w(p))−p∥≤Cεm∥p∥
\\left\\| T_{w \\to u}(T_{u \\to w}(p)) – p \\right\\| \\le C \\varepsilon_m \\|p\\|
∥Tw→u(Tu→w(p))−p∥≤Cεm∥p∥
自测要求:
∥Tw→u(Tu→w(p))−p∥≤10−9
\\left\\| T_{w \\to u}(T_{u \\to w}(p)) – p \\right\\| \\le 10^{-9}
∥Tw→u(Tu→w(p))−p∥≤10−9
45° 正向算例要求 ≤10−12\\le 10^{-12}≤10−12。
3.6 零回归条件
默认 UCS = 世界系时:
o=0,θ=0
o = 0,\\qquad \\theta = 0
o=0,θ=0
此时:
Tu→w(p)=p,Tw→u(p)=p
T_{u \\to w}(p) = p,\\qquad T_{w \\to u}(p) = p
Tu→w(p)=p,Tw→u(p)=p
所有新增带默认值的 UCS 参数取缺省值时,旧调用路径逐位等价。
4 各模块改动清单
4.1 新增 src/core/Ucs.h
- struct Ucs:name/origin/angleRad + xAxis() / yAxis() / toWorld() / toUcs() / isWorld() / describe()。
4.2 SketchModel (core)
- 状态:
- currentUcs_:默认世界;
- ucsTable_:内存表;
- coordDisplayUcs_:读数模式;
- lastInputPointWorld_:相对坐标基准点。
- API:
- setCurrentUcs() / currentUcs();
- toWorld() / toUcs();
- parsePointToWorld(s, base, out);
- displayCoord();
- ucsSave/ucsDelete/ucsSetCurrent/ucsHas/ucsGet/ucsNames/ucsCount。
- 信号:ucsChanged(),状态栏 / 视图联动;setCurrentUcs 另发 viewChanged 驱动重绘。
4.3 点解析(UCS 感知)
SketchModel::parsePointToWorld 支持四种语法,均经 toWorld 收口。
| x,y[,z] | 绝对(UCS 局部) | UCS 原点 |
| @dx,dy | 相对笛卡尔 | base(世界)转局部后偏移 |
| dist<angle | 绝对极坐标 | UCS 原点,UCS X = 0∘0^\\circ0∘ |
| @dist<angle | 相对极坐标 | base,UCS X = 0∘0^\\circ0∘ |
接线点:
- CommandLine::onReturn:键盘坐标输入改走 parsePointToWorld,基准 = lastInputPointWorld();UCS = 世界时与旧 tryParsePoint 行为逐位一致;
- GraphicsView::injectPoint:提交后回写 lastInputPointWorld_,链式 @ 基准;
- commitDynInput:偏移改沿 ucs.xAxis()/yAxis() 分解,updateDynBox 预填角减去 UCS 旋转角,显示口径 = 提交口径。
4.4 ucs 命令(core/Commands)
五种定义:
| ucs world | 恢复世界系 |
| ucs view | 按当前视图定义 |
| ucs 3p p1 p2 [p3] | 三点定义 |
| ucs object <id> | 按对象定义 |
| ucs z <x,y> <角°> | 原点 + 角度 |
便捷:
ucs origin <x,y> [角°]
CRUD:
ucs save|set|restore|delete|list
其中 set 与 restore 同义,WORLD 不可删。
读数切换:
ucs coords wcs|ucs
便捷切换:
ucs <已存在名>
登记于 registerExact("ucs", …),紧邻 plane。
4.5 Snap 按 UCS 轴对齐(零回归设计)
三个函数追加带默认值的 UCS 参数,缺省 = 世界轴,既有调用零改动:
- polarAngles(cfg, baseDir, ucsOffsetDeg=0):极轴角基准整体偏移;
- track(…, ucsAngleRad=0):OTRACK/TK 的水平/垂直对齐线改为在 UCS 局部系内做轴对齐,落点转回世界系;ucsAngleRad=0 时两次变换恒等,逐位等价旧实现;
- applyInputConstraints(…, ucsAngleRad=0):正交锁轴与栅格量化均转 UCS 局部系执行。
4.6 GraphicsView 按 UCS 渲染
- 网格:UCS ≠ 世界时转 UCS 局部系生成网格线,可见区四角转局部取包围盒保证覆盖,经 painter translate(UCS 原点) + rotate(UCS 角) 映射回世界;UCS = 世界走原快路。
- 坐标轴图标:save/translate/rotate 后绘制,落在 UCS 原点、按 UCS 角旋转;UCS = 世界时变换恒等。
- 极轴射线:与追踪吸附共用同一 polarAngles 入口,传 UCS 偏移,所见即所得。
- 正交引导线:沿 ucs.xAxis()/yAxis() 绘制。
- HUD:显示当前 UCS 名称/原点/旋转角,世界系显示 WCS。
- 坐标读数:cursorMoved 改发 model_->displayCoord(w),WCS/UCS 随模式。
- 视图矩阵不变式保持:applyTransform 的无旋转映射:
screenx=wx⋅zoom+panX
\\text{screen}_x = w_x \\cdot \\mathrm{zoom} + \\mathrm{panX}
screenx=wx⋅zoom+panX
screeny=−wy⋅zoom+panY
\\text{screen}_y = -w_y \\cdot \\mathrm{zoom} + \\mathrm{panY}
screeny=−wy⋅zoom+panY
绝不旋转。UCS 旋转全部用几何层 UCS 基实现,避免破坏大量依赖该不变式的既有自测。
- DYN:提交/预填角均以 UCS X 为 0∘0^\\circ0∘ 基准。
4.7 状态栏 UCS 指示器
- StatusBar::setUcsInfo() 新标签 ⌖ WCS / ⌖ 名称 角度°;
- tooltip 提示 ucs 命令用法;
- ModelMediator 订阅 ucsChanged + 启动回显一次;
- 读数切到 UCS 时附加“(读数 UCS)”提示。
4.8 ConstraintSolver 不动(刻意决策)
t_horizontal/t_vertical/t_angle 等约束自测是世界 X 基准的回归用例。约束层若随 UCS 旋转将全面破坏“约束 = 几何恒等关系”的语义。约束继续以世界系为唯一基准,与“UCS 只是输入/显示变换”的定位一致。
5 自测覆盖(t_ucs,共 24 条 CHECK)
p=(100cos45∘,100sin45∘)
p = (100\\cos 45^\\circ, 100\\sin 45^\\circ)
p=(100cos45∘,100sin45∘)
误差 ≤10−6\\le 10^{-6}≤10−6;另覆盖绝对笛卡尔、绝对极坐标、相对笛卡尔、世界系零回归 4 例;
(cos30∘,sin30∘)
(\\cos 30^\\circ, \\sin 30^\\circ)
(cos30∘,sin30∘)
世界系回到 (1,0)(1,0)(1,0);
6 创新点与讨论
6.1 形式化 UCS 为 SE(2)SE(2)SE(2) 子集
本文将 UCS 明确定义为二维刚性变换群 SE(2)SE(2)SE(2) 的子集,并给出正逆变换、正交性与误差界。该形式化使坐标换算从工程约定提升为可证明的数学对象。
6.2 插入层 = 输入/显示层
提出“UCS 只存在于输入/显示边界,存储层始终为世界坐标”的架构边界。该边界保证:
- 存档格式零改动;
- 几何算法无感;
- 既有回归零破坏。
可形式化为:
Store=WCS,Input=Tu→w(UCS),Display=Tw→u(WCS)
\\mathrm{Store} = \\mathrm{WCS},\\qquad
\\mathrm{Input} = T_{u \\to w}(\\mathrm{UCS}),\\qquad
\\mathrm{Display} = T_{w \\to u}(\\mathrm{WCS})
Store=WCS,Input=Tu→w(UCS),Display=Tw→u(WCS)
6.3 单一换算入口
所有坐标变换收口到 SketchModel::toWorld() / toUcs(),杜绝方向不一致。该设计可视为“变换单例”模式,在架构上强制唯一性。
6.4 零回归设计模式
新增参数带默认值,默认 UCS = 世界系,旧调用路径逐位等价。该模式可概括为:
默认参数+世界系恒等⇒零回归
\\text{默认参数} + \\text{世界系恒等} \\Rightarrow \\text{零回归}
默认参数+世界系恒等⇒零回归
6.5 刻意不序列化
命名 UCS 表不入档,避免 JSON 顶层键集变化。该决策以自测断言固化:
"ucs"∉Keys(JSON)
\\texttt{"ucs"} \\notin \\mathrm{Keys}(\\mathrm{JSON})
"ucs"∈/Keys(JSON)
"ucsTable"∉Keys(JSON)
\\texttt{"ucsTable"} \\notin \\mathrm{Keys}(\\mathrm{JSON})
"ucsTable"∈/Keys(JSON)
6.6 动态 UCS 扩展路径
动态 UCS 可在 snapWorld 入口前插入临时 Ucs,复用全部机制:
Tdyn=T(odyn,θdyn)
T_{\\text{dyn}} = T(o_{\\text{dyn}}, \\theta_{\\text{dyn}})
Tdyn=T(odyn,θdyn)
无需改动存储层与约束层。
7 已知边界与后续可选项
- 动态 UCS:绘制时对临时工作平面自动吸附,列为可选子项,未实现;静态命名 UCS 全链路已正确,动态 UCS 可在 snapWorld 入口前插入临时 Ucs 而复用全部机制。
- 约束求解不随 UCS 旋转;如未来需要“UCS 相对约束”应作为独立约束类型设计。
- UCS 表不持久化是刻意取舍;若需随图保存应走“顶层键只追加”路径并同步黄金样本。
- CommandContext::parsePoint(脚本/命令行整行命令的绝对点)保持世界系语义——键盘交互入口已 UCS 化,脚本参数保持确定性解析,避免既有脚本回归。
8 结论
本文以二维刚性变换为数学基础,构建了静态命名 UCS 体系。通过“插入层 = 输入/显示层”的架构边界、单一换算入口、零回归设计模式与刻意不序列化决策,系统在支持斜视图、局部斜坐标制图的同时,保证存档格式零改动、既有算法无感、全量自测零回归。新增 t_ucs 24 条 CHECK 覆盖数学恒等、命令定义、极轴/正交/栅格、读数切换与不入档断言。动态 UCS 可作为后续可选子项,在现有机制上无缝扩展。
附录 A 符号表
| ooo | UCS 原点,世界坐标 |
| θ\\thetaθ | UCS 绕 Z 轴旋转角 |
| R(θ)R(\\theta)R(θ) | 二维旋转矩阵 |
| Tu→wT_{u \\to w}Tu→w | UCS 局部到世界的正变换 |
| Tw→uT_{w \\to u}Tw→u | 世界到 UCS 局部的逆变换 |
| pwp_wpw | 世界坐标 |
| pup_upu | UCS 局部坐标 |
| SE(2)SE(2)SE(2) | 二维刚性变换群 |
| SO(2)SO(2)SO(2) | 二维旋转群 |
| xaxisx_{\\text{axis}}xaxis | UCS 局部 X 轴单位向量 |
| yaxisy_{\\text{axis}}yaxis | UCS 局部 Y 轴单位向量 |
附录 B 公式汇总
正变换:
pw=o+R(θ)pu
p_w = o + R(\\theta) p_u
pw=o+R(θ)pu
逆变换:
pu=R(−θ)(pw−o)
p_u = R(-\\theta)(p_w – o)
pu=R(−θ)(pw−o)
旋转矩阵:
R(θ)=(cosθ−sinθsinθcosθ)
R(\\theta) =
\\begin{pmatrix}
\\cos\\theta & -\\sin\\theta \\\\
\\sin\\theta & \\cos\\theta
\\end{pmatrix}
R(θ)=(cosθsinθ−sinθcosθ)
正交性:
R(θ)⊤R(θ)=I,R(θ)−1=R(θ)⊤=R(−θ)
R(\\theta)^\\top R(\\theta) = I,\\qquad
R(\\theta)^{-1} = R(\\theta)^\\top = R(-\\theta)
R(θ)⊤R(θ)=I,R(θ)−1=R(θ)⊤=R(−θ)
轴向量:
xaxis=(cosθ,sinθ,0)
x_{\\text{axis}} = (\\cos\\theta, \\sin\\theta, 0)
xaxis=(cosθ,sinθ,0)
yaxis=(−sinθ,cosθ,0)
y_{\\text{axis}} = (-\\sin\\theta, \\cos\\theta, 0)
yaxis=(−sinθ,cosθ,0)
绝对极坐标:
pu=o+d⋅(cos(α+θ),sin(α+θ))
p_u = o + d \\cdot (\\cos(\\alpha + \\theta), \\sin(\\alpha + \\theta))
pu=o+d⋅(cos(α+θ),sin(α+θ))
零回归条件:
o=0,θ=0⇒Tu→w=Tw→u=id
o = 0,\\quad \\theta = 0 \\Rightarrow T_{u \\to w} = T_{w \\to u} = \\mathrm{id}
o=0,θ=0⇒Tu→w=Tw→u=id
不入档断言:
"ucs"∉Keys(JSON)
\\texttt{"ucs"} \\notin \\mathrm{Keys}(\\mathrm{JSON})
"ucs"∈/Keys(JSON)
"ucsTable"∉Keys(JSON)
\\texttt{"ucsTable"} \\notin \\mathrm{Keys}(\\mathrm{JSON})
"ucsTable"∈/Keys(JSON)
附录 C 自测断言摘要
| C1 | 默认 UCS = 世界系 | isWorld 为真,往返恒等 |
| C2 | 轴向量单位正交 | ∣xaxis∣=∣yaxis∣=1|x_{\\text{axis}}| = |y_{\\text{axis}}| = 1∣xaxis∣=∣yaxis∣=1,点积为 0 |
| C3 | 双向往返误差 | ≤10−9\\le 10^{-9}≤10−9 |
| C4 | 45° 正向算例 | 误差 ≤10−12\\le 10^{-12}≤10−12 |
| C5 | @100<0 落点 | (100cos45∘,100sin45∘)(100\\cos45^\\circ, 100\\sin45^\\circ)(100cos45∘,100sin45∘),误差 ≤10−6\\le 10^{-6}≤10−6 |
| C6 | ucs 五种定义 | origin + angle 正确 |
| C7 | ucs CRUD | save/restore/delete/set/list 正确 |
| C8 | 极轴偏移 | 含 30∘30^\\circ30∘ / 120∘120^\\circ120∘,不含 0∘0^\\circ0∘ |
| C9 | 正交锁轴 | UCS 90∘90^\\circ90∘ 锁到世界 Y 轴 |
| C10 | 栅格量化 | UCS 45∘45^\\circ45∘ 沿 UCS 轴量化 |
| C11 | 读数切换 | WCS 与 UCS 值不同 |
| C12 | 网格方向 | UCS 30∘30^\\circ30∘ 主方向为 (cos30∘,sin30∘)(\\cos30^\\circ, \\sin30^\\circ)(cos30∘,sin30∘) |
| C13 | 不入档 | JSON 顶层无 ucs / ucsTable |
总结:本文提出并实现了一套静态命名 UCS 体系,以二维刚性变换为数学核心,以“输入/显示边界插入”为架构原则,以“单一换算入口”为一致性保障,以“零回归设计”为工程约束,以“刻意不序列化”为兼容性决策。系统支持斜视图与局部斜坐标制图,同时保持存档格式零改动、既有算法无感、全量自测零回归。动态 UCS 可在现有机制上无缝扩展,为后续斜向制图与临时工作平面提供可复用路径。





