> **本文回答**：平面视图（PLAN）= "把视图旋转到与当前 UCS 对齐"。核心公式 `twistAngle = -UCSXANG`。完整流程：① 设 `UCSXANG`（[ucs](ucs.md)）；② 写 `Engine.currentSpace.twistAngle = -Engine.currentSpace.UCSXANG`；③ 改完值后再 `Engine.undoManager.plan_undoMark(oldTwistAngle)`（UCS/PLAN 的 mark 构造时读取当前值作 redo 目标，必须**先改再 mark**）+ `regenGrip + redraw`。命令 `PLAN` 只有 `C`（当前 UCS，默认）/ `W`（WCS）两个选项。

## 一、最小用法（自动旋转 60°）

```js
function setPlanViewRotation(angleInDegrees) {
  const angRad = angleInDegrees * Math.PI / 180;

  const oldOrg         = Engine.currentSpace.UCSORG.clone();
  const oldUcsAngle    = Engine.currentSpace.UCSXANG;
  const oldTwistAngle  = Engine.currentSpace.twistAngle;

  // ① 设 UCS X 轴角度：先改值，再 mark（传旧值）
  Engine.currentSpace.UCSXANG = angRad;
  Engine.undoManager.ucs_undoMark(oldOrg, oldUcsAngle);
  Engine.pcanvas.updateUcsIsWcs();

  // ② 视图与 UCS 对齐：同样先改值，再 mark
  Engine.currentSpace.twistAngle = -Engine.currentSpace.UCSXANG;
  Engine.undoManager.plan_undoMark(oldTwistAngle);

  // ③ 状态栏 + 夹点 + 重绘
  if (Engine.view.coordsBar) {
    Engine.view.coordsBar.updateCoordsTitle();
  }
  Engine.pcanvas.regenGrip();
  Engine.pcanvas.redraw();
}

setPlanViewRotation(60);    // 旋转 60°
```

MCP 参考：`vjcad/example/view/11planview.js`（官方示例 `plan_undoMark` 在改值之前调用，redo 会失效；上面已按源码顺序修正）。

## 二、重置为 WCS 平面视图（无旋转）

```js
function resetToWcsPlanView() {
  const oldOrg         = Engine.currentSpace.UCSORG.clone();   // 旧原点（不能传改完后的新原点）
  const oldUcsAngle    = Engine.currentSpace.UCSXANG;
  const oldTwistAngle  = Engine.currentSpace.twistAngle;

  Engine.currentSpace.UCSORG  = new Point2D();
  Engine.currentSpace.UCSXANG = 0;
  Engine.undoManager.ucs_undoMark(oldOrg, oldUcsAngle);
  Engine.pcanvas.updateUcsIsWcs();

  Engine.currentSpace.twistAngle = 0;
  Engine.undoManager.plan_undoMark(oldTwistAngle);

  if (Engine.view.coordsBar) {
    Engine.view.coordsBar.updateCoordsTitle();
  }
  Engine.pcanvas.regenGrip();
  Engine.pcanvas.redraw();
}
```

MCP 参考：`vjcad/example/view/11planview.js`。

## 三、命令版

```
PLAN
平面视图 [UCS(C)/WCS(W)] <C>: C      ← 当前 UCS 平面视图（twistAngle = -UCSXANG，并自动全图缩放）
PLAN
平面视图 [UCS(C)/WCS(W)] <C>: W      ← WCS 平面视图（twistAngle = 0）
```

代码触发：

```js
Engine.editor.executerWithOp('PLAN');
```

MCP 参考：`vjcad/example/view/11planview.js`。

## 四、关键变量速查

| 变量 | 含义 |
|---|---|
| `Engine.currentSpace.UCSORG` | UCS 原点 |
| `Engine.currentSpace.UCSXANG` | UCS X 轴角度（弧度） |
| `Engine.currentSpace.twistAngle` | 视图相对 WCS 的旋转角度（通常 = `-UCSXANG`） |
| `Engine.undoManager.ucs_undoMark(oldOrg, oldAng)` | UCS 撤销标记 |
| `Engine.undoManager.plan_undoMark(oldTwistAngle)` | 平面视图撤销标记 |
| `Engine.pcanvas.updateUcsIsWcs()` | 内部缓存"UCS 是否等于 WCS" |
| `Engine.pcanvas.regenGrip()` | 夹点重生成 |

## 反例

- 改了 `UCSXANG` 没改 `twistAngle`：UCS 旋转了，但视图没跟着转，看上去倾斜了。
- 改了 `twistAngle` 没 `regenGrip + redraw`：屏幕没刷新。
- 想 "永远旋转 30 度的图纸" → 应保存到 `cadView` / 文档级配置，不要靠用户手动触发 PLAN。

## 参考（官方文档 MCP）

- 文档：`vjcad/doc/view/index.md`、`vjcad/doc/view/view-commands.md`
- 示例：`vjcad/example/view/11planview.js`、`vjcad/example/view/10ucs.js`
