> **本文回答**：vjcad 坐标系有 WCS（世界）/ UCS（用户）/ DCS（显示），常用转换在 `Engine.trans` 与 `Engine.pcanvas.trans` 上：`CanvasToWcs / WcsToCanvas` 用于鼠标 ↔ 图纸；`WcsToUcs / UcsToWcs / WcsToDcs / DcsToWcs / UcsToDcs / DcsToUcs` 在用户坐标系 / 显示坐标系之间转换；快捷写法 `Engine.canvasToWcs(point)`。

## 一、坐标系关系

> 引自 `vjcad/doc/guide/architecture.md`：

```
WCS（世界坐标系，绝对参考）  <-- WcsToUcs / UcsToWcs -->  UCS（用户坐标系，工作平面）
        ^                                                        ^
        |                                                        |
WcsToDcs / DcsToWcs                                       UcsToDcs / DcsToUcs
        v                                                        v
                  DCS（显示坐标系，屏幕像素）
```

## 二、最常用：鼠标 → 图纸

```js
// 写法 A（示例里常见）
const canvas = Engine.pcanvas;
canvas.div.addEventListener('mousemove', (e) => {
  const canvasPt = new Point2D(e.offsetX, e.offsetY);
  const wcsPt    = canvas.trans.CanvasToWcs(canvasPt);
  console.log(`X: ${wcsPt.x.toFixed(2)}, Y: ${wcsPt.y.toFixed(2)}`);
});

// 写法 B（命令文档里常见）
const wcsPt2 = Engine.trans.CanvasToWcs(canvasPt);

// 写法 C（架构文档里出现）
const wcsPt3 = Engine.canvasToWcs(canvasPt);
```

> **来源命名差异**：`Engine.trans.CanvasToWcs` 来自 `vjcad/doc/command/api-reference.md`；`Engine.pcanvas.trans.CanvasToWcs` 来自 `vjcad/example/basic/03viewermode.js` 与 `04viewerremote.js`；`Engine.canvasToWcs` 来自 `vjcad/doc/guide/architecture.md`。三处都有效，按你 IDE 里能解析到的即可。

MCP 参考：`vjcad/example/basic/03viewermode.js`、`vjcad/example/basic/04viewerremote.js`、`vjcad/doc/command/api-reference.md`、`vjcad/doc/guide/architecture.md`。

## 三、其他转换

```js
// WCS <-> UCS（用于用户界面显示）
const ucsPt  = Engine.trans.WcsToUcs(wcsPt);
const wcsPt2 = Engine.trans.UcsToWcs(ucsPt);

// WCS <-> DCS（用于屏幕绘制）
const dcsPt  = Engine.trans.WcsToDcs(wcsPt);
const wcsPt3 = Engine.trans.DcsToWcs(dcsPt);

// UCS <-> DCS
const dcsPt2 = Engine.trans.UcsToDcs(ucsPt);
const ucsPt2 = Engine.trans.DcsToUcs(dcsPt2);
```

MCP 参考：`vjcad/doc/guide/architecture.md`。

## 四、`Point2D` 工具

```js
import { Point2D } from 'vjcad';

const p1 = new Point2D(0, 0);
const p2 = new Point2D(100, 100);

p1.x; p1.y;
p1.clone();
p1.move(from, to);
p1.rotate(angle, center);
p1.offset(delta);
// ⚠️ Point2D 没有 distanceTo（distanceTo 只在 GeoPoint 上）；
// 两点距离用 Math.hypot(p2.x - p1.x, p2.y - p1.y)
```

MCP 参考：`vjcad/doc/command/api-reference.md`。

## 五、UCS 的程序操作

UCS 的旋转、原点设置、`PLAN` 重置等详见：

- [view/ucs](../view/ucs.md)
- [view/plan-view](../view/plan-view.md)

## 反例

- 用 `e.clientX / e.clientY` 直接当画布坐标：应使用相对画布的 `e.offsetX / e.offsetY`，再 `CanvasToWcs`。
- 把 `Engine.trans.CanvasToWcs` 与 `Engine.pcanvas.trans.CanvasToWcs` 当作两套不同 API：实际是同一对象的不同访问路径。

## 参考（官方文档 MCP）

- 文档：`vjcad/doc/guide/architecture.md`、`vjcad/doc/command/api-reference.md`
- 示例：`vjcad/example/basic/03viewermode.js`、`vjcad/example/basic/04viewerremote.js`
