> **本文回答**：多段线推荐三种写法：① `pl.setPoints([[x, y], ...])` 简化批量；② `pl.bulgePoints.add(new BulgePoint(new Point2D(x, y), bulge))` 手动加凸度；③ `pl.addVertex([x, y])` 逐点。多段线属性还有 `isClosed`、`globalWidth`（全局线宽）等；圆角矩形、Donut、Polygon 都是 PolylineEnt + 凸度。

## 一、最简洁：批量点 + 闭合

```js
const pl = new PolylineEnt();
pl.setPoints([
  [0, 0],
  [100, 0],
  [100, 50],
  [0, 50]
]);
pl.isClosed = true;
pl.setDefaults();
Engine.addEntities(pl);
```

MCP 参考：`vjcad/example/entity/all/01entities.js`、`vjcad/example/entity/polyline/02rectangle.js`。

## 二、带凸度（直线段 + 弧段）

```js
import { Engine, PolylineEnt, BulgePoints, BulgePoint, Point2D } from 'vjcad';

const pl = new PolylineEnt();
pl.bulgePoints.add(new BulgePoint(new Point2D(0, 0),    0));
pl.bulgePoints.add(new BulgePoint(new Point2D(100, 0),  0.5));   // 凸度 0.5 的弧段
pl.bulgePoints.add(new BulgePoint(new Point2D(150, 50), 0));
pl.bulgePoints.add(new BulgePoint(new Point2D(150, 100), 0));
pl.setDefaults();
Engine.addEntities(pl);
```

凸度（bulge）含义（来自 `vjcad/doc/guide/quick-start.md`）：

| bulge | 含义 |
|---|---|
| `0` | 直线段 |
| `>0` | 逆时针弧段 |
| `<0` | 顺时针弧段 |
| `1` | 半圆弧 |

## 三、`addVertex` 逐点

```js
const pl = new PolylineEnt();
for (const [x, y] of pts) pl.addVertex([x, y]);
pl.isClosed = false;
pl.setDefaults();
Engine.addEntities(pl);
```

MCP 参考：`vjcad/example/command/04statemachine.js`、`vjcad/example/input/05getinteger.js`。

## 四、属性

| 属性 | 说明 |
|---|---|
| `isClosed` | 闭合 |
| `globalWidth` | 全局线宽（如 Donut 用） |
| `bulgePoints` | 顶点集合 |
| `length` | 周长 |
| `area` | 面积（仅对无凸度、闭合、不自交的多段线有效，否则返回 `-1`，如圆角矩形） |

MCP 参考：`vjcad/doc/entity/polyline-ent.md`、`vjcad/doc/guide/quick-start.md`、`vjcad/example/entity/polyline/04properties.js`。

## 五、特殊形状

### Donut（圆环）

```js
const innerR = 12, outerR = 28;
const middleR = (innerR + outerR) / 2;
const lineWidth = outerR - innerR;
const arcParam = (middleR * Math.sqrt(2)) / 2;
const bulge = (middleR - arcParam) / arcParam;

const donut = new PolylineEnt();
donut.bulgePoints.add(new BulgePoint(new Point2D( middleR, 0), bulge));
donut.bulgePoints.add(new BulgePoint(new Point2D(0,  middleR), bulge));
donut.bulgePoints.add(new BulgePoint(new Point2D(-middleR, 0), bulge));
donut.bulgePoints.add(new BulgePoint(new Point2D(0, -middleR), bulge));
donut.bulgePoints.add(new BulgePoint(new Point2D( middleR, 0), 0));
donut.isClosed = false;
donut.globalWidth = lineWidth;
donut.setDefaults();
Engine.addEntities(donut);
```

MCP 参考：`vjcad/example/entity/all/01entities.js`、`vjcad/example/entity/donut/01create.js`。

### 圆角矩形（用半圆凸度）

```js
const r = 8, w = 60, h = 40;
const minX = -w/2, maxX = w/2, minY = -h/2, maxY = h/2;
const bulge = Math.tan(Math.PI / 8);

const rect = new PolylineEnt();
rect.bulgePoints.add(new BulgePoint(new Point2D(minX + r, minY), 0));
rect.bulgePoints.add(new BulgePoint(new Point2D(maxX - r, minY), bulge));
rect.bulgePoints.add(new BulgePoint(new Point2D(maxX, minY + r), 0));
rect.bulgePoints.add(new BulgePoint(new Point2D(maxX, maxY - r), bulge));
rect.bulgePoints.add(new BulgePoint(new Point2D(maxX - r, maxY), 0));
rect.bulgePoints.add(new BulgePoint(new Point2D(minX + r, maxY), bulge));
rect.bulgePoints.add(new BulgePoint(new Point2D(minX, maxY - r), 0));
rect.bulgePoints.add(new BulgePoint(new Point2D(minX, minY + r), bulge));
rect.isClosed = true;
rect.setDefaults();
Engine.addEntities(rect);
```

MCP 参考：`vjcad/example/entity/all/01entities.js`。

### Polygon（正多边形 = 闭合 PolylineEnt）

```js
function createPolygon(center, radius, sides) {
  const pl = new PolylineEnt();
  for (let i = 0; i < sides; i++) {
    const ang = (2 * Math.PI * i) / sides - Math.PI / 2;
    pl.addVertex([
      center.x + radius * Math.cos(ang),
      center.y + radius * Math.sin(ang)
    ]);
  }
  pl.isClosed = true;
  pl.setDefaults();
  return pl;
}
```

MCP 参考：`vjcad/example/input/05getinteger.js`、`vjcad/example/entity/polygon/01create.js`。

### DLine（双线）/ Box / Parallelogram / PixelPoint

均有专门示例：`vjcad/example/entity/dline/01create.js`、`box/01create.js`、`parallelogram/01create.js`、`pixelpoint/01create.js`。

## 反例

- 设了 `globalWidth` 但忘了 `setDefaults` / 颜色：线宽生效但颜色用了默认。
- 把 `bulge` 当 "弧度角"：bulge 没有角度单位，是按弦中点到弧线偏离的几何量。
- `setPoints` 后又 `bulgePoints.clear()`：会把刚加的点丢掉。

## 参考（官方文档 MCP）

- 文档：`vjcad/doc/entity/polyline-ent.md`、`vjcad/doc/guide/quick-start.md`
- 示例：`vjcad/example/entity/all/01entities.js`、`vjcad/example/entity/polyline/01create.js`～`04properties.js`、`vjcad/example/entity/donut/01create.js`、`vjcad/example/entity/box/01create.js`、`vjcad/example/entity/polygon/01create.js`、`vjcad/example/entity/parallelogram/01create.js`、`vjcad/example/entity/pixelpoint/01create.js`、`vjcad/example/entity/dline/01create.js`
