# 常用实体

日常开发中最常用的实体类型。

## LineEnt - 直线

```javascript
const { LineEnt, Engine } = vjcad;

// 创建直线
const line = new LineEnt([0, 0], [100, 100]);  // 起点, 终点
line.setDefaults();
line.color = 1;  // 红色
Engine.addEntities(line);
```

**属性**：
- `startPoint` / `endPoint` - 起点/终点 (Point2D)
- `Length` - 长度（只读）
- `color` - 颜色
- `layer` - 图层
- `lineType` - 线型
- `lineTypeScale` - 线型比例

---

## CircleEnt - 圆

```javascript
const { CircleEnt, Engine } = vjcad;

// 创建圆
const circle = new CircleEnt([50, 50], 30);  // 圆心, 半径
circle.setDefaults();
circle.color = 3;  // 绿色
Engine.addEntities(circle);
```

**属性**：
- `center` - 圆心 (Point2D)
- `radius` - 半径
- `area` - 面积（只读）
- `circumference` - 周长（只读）

---

## ArcEnt - 圆弧

```javascript
const { ArcEnt, Point2D, Engine } = vjcad;

// 方式1: 圆心 + 半径 + 角度（弧度）
const arc = new ArcEnt([50, 50], 30, 0, Math.PI / 2);  // 0° 到 90°
arc.setDefaults();
Engine.addEntities(arc);

// 方式2: 三点定弧
const arc2 = new ArcEnt();
arc2.initBy3Pt(new Point2D(0, 0), new Point2D(50, 30), new Point2D(100, 0));
arc2.setDefaults();
Engine.addEntities(arc2);
```

**属性**：
- `center` - 圆心
- `radius` - 半径
- `startAngle` / `endAngle` - 起始/终止角度（弧度）
- `startPoint` / `endPoint` - 起点/终点（只读）
- `midPoint` - 中点（只读）
- `length` - 弧长（只读）
- `totalAngle` - 圆心角（只读）
- `isClockwise` - 是否顺时针（只读）

**方法**：
- `initBy3Pt(p1, p2, p3)` - 通过三点创建圆弧

---

## PolylineEnt - 多段线

```javascript
const { PolylineEnt, BulgePoints, BulgePoint, Engine } = vjcad;

// 方式1: 使用 setPoints（推荐）
const pline = new PolylineEnt();
pline.setPoints([
    [0, 0],
    [100, 0],
    [100, 60],
    [0, 60]
]);
pline.isClosed = true;  // 闭合
pline.setDefaults();
Engine.addEntities(pline);

// 方式2: 链式 addPoint
const pline2 = new PolylineEnt();
pline2.addPoint([0, 0])
      .addPoint([50, 0], 0.5)  // 带凸度的弧段
      .addPoint([100, 0]);
pline2.setDefaults();
Engine.addEntities(pline2);

// 方式3: 带圆弧段的多段线
const pline3 = new PolylineEnt();
pline3.setPoints([
    [0, 0],              // 0→1 直线段
    [[50, 0], 0.5],      // 1→2 弧段（凸度记在段起点上，0.5 逆时针）
    [[100, 0], -0.5],    // 2→3 弧段（负凸度，顺时针）
    [100, 50]            // 末点：开放多段线的末点凸度不生效（仅 isClosed 时作用于末点→首点段）
]);
pline3.setDefaults();
Engine.addEntities(pline3);
```

**凸度说明**（凸度作用于"本顶点→下一顶点"这一段）：
- `0` - 直线段
- `1` - 半圆弧（逆时针，圆心角180°）
- `-1` - 半圆弧（顺时针）
- `bulge = tan(圆心角/4)`，圆心角单位为弧度
- 常用值速查：
  - 90°圆角(R角) → `bulge = tan(π/8) ≈ 0.4142`
  - 60°弧 → `bulge = tan(π/12) ≈ 0.2679`
  - 120°弧 → `bulge = tan(π/6) ≈ 0.5774`
  - 180°半圆 → `bulge = 1.0`

**注意**：`bulge=1` 是半圆弧（180°），不是 90° 圆角！
绘制圆角矩形时应使用 `Math.tan(Math.PI / 8)` ≈ 0.4142。

**属性**：
- `bulgePoints` - 顶点集合 (BulgePoints)
- `isClosed` - 是否闭合
- `length` - 总长度（只读）
- `area` - 面积（闭合时，只读）
- `isCCW` - 是否逆时针（只读）
- `globalWidth` - 全局宽度

**方法**：
- `setPoints(points)` - 批量设置点
- `addPoint([x,y], bulge?)` - 添加点（支持链式调用）
- `addPoints(points)` - 批量追加点
- `getPoints()` - 获取所有顶点坐标
- `getPointsWithBulge()` - 获取顶点和凸度信息
- `getSubEnts()` - 获取子实体（线段和弧段）

---

## TextEnt - 单行文字

```javascript
const { TextEnt, Engine } = vjcad;

const text = new TextEnt();
text.insertionPoint = [0, 100];  // 插入点
text.text = "Hello WebCAD";      // 文本内容
text.height = 10;                // 字高
text.rotation = 0;               // 旋转角度（弧度）
text.textAlignment = 5;          // 对齐方式（见下方）
text.setDefaults();
text.color = 2;
Engine.addEntities(text);
```

**文本对齐方式（textAlignment）**：
```
7=TopLeft     8=TopCenter     9=TopRight
4=MidLeft     5=MidCenter     6=MidRight
1=Left        2=Center        3=Right (基线对齐)
```

**特殊字符**：
- `%%d` → °（度）
- `%%c` → Ø（直径）
- `%%p` → ±（正负）

**属性**：
- `insertionPoint` - 插入点
- `text` - 文本内容
- `height` - 字高
- `rotation` - 旋转角度（弧度）
- `textAlignment` - 对齐方式 (1-9)
- `widthFactor` - 宽度因子
- `obliqueAngle` - 倾斜角度（**度**，与 `rotation` 的弧度不同；直接作为 obliqueDeg 传给文字渲染）

---

## MTextEnt - 多行文字

```javascript
const { MTextEnt, Engine } = vjcad;

const mtext = new MTextEnt();
mtext.insertionPoint = [0, 100];
mtext.text = "第一行\n第二行\n第三行";  // \n 换行
mtext.height = 8;
mtext.maxWidth = 80;  // 超出宽度自动换行
mtext.setDefaults();
Engine.addEntities(mtext);
```

**MText 格式代码**（使用 `contents` 属性）：
```javascript
// 颜色
mtext.contents = "{\\C1;红色}{\\C2;黄色}{\\C3;绿色}";

// 字体大小
mtext.contents = "{\\H1.5x;大号} 普通 {\\H0.7x;小号}";

// 样式
mtext.contents = "{\\L下划线} {\\O上划线} {\\K删除线}";

// 换行
mtext.contents = "第一行\\P第二行";
```

**格式代码速查**：
| 代码 | 功能 |
|------|------|
| `\Cn;` | 颜色（1红 2黄 3绿 4青 5蓝 6洋红 7白）|
| `\L` / `\l` | 下划线 开/关 |
| `\O` / `\o` | 上划线 开/关 |
| `\K` / `\k` | 删除线 开/关 |
| `\Hn.nx;` | 相对高度（如 `\H1.5x;`）|
| `\Wn;` | 宽度因子 |
| `\P` | 换行 |
| `{}` | 格式分组 |

**属性**：
- `insertionPoint` - 插入点
- `text` - 文本内容（支持 \n 换行）
- `contents` - 原生 MText 格式内容
- `height` - 字高
- `maxWidth` - 最大宽度（自动换行）
- `textAttachment` - 附着点位置 (1-9)
- `rotation` - 旋转角度
- `rowSpcFac` - 行间距因子
- `showBorder` - 是否显示边框
- `backgroundFill` - 是否启用背景
- `backgroundFillColor` - 背景颜色
- `backgroundScaleFactor` - 背景扩展比例

---

## 较少使用的实体

### EllipseEnt - 椭圆

```javascript
const { EllipseEnt, Engine } = vjcad;

const ellipse = new EllipseEnt();
ellipse.center = [50, 50];
ellipse.majorRadius = 40;      // 长轴半径（number）
ellipse.minorRadius = 20;      // 短轴半径（number）
// 等价：new EllipseEnt([50,50], 40, 20, 0)；majorAxis 是长轴角度（弧度 number），不是向量
ellipse.setDefaults();
Engine.addEntities(ellipse);
```

### SplineEnt - 样条曲线

```javascript
const { SplineEnt, Engine } = vjcad;

// 拟合点模式：曲线精确经过所有点
const spline = new SplineEnt();
spline.setFitPoints([
    [0, 0],
    [50, 100],
    [100, 50],
    [150, 100]
]);
spline.setDefaults();
Engine.addEntities(spline);

// 控制点模式：控制点"拉动"曲线但不经过
const spline2 = new SplineEnt();
spline2.setControlPoints([
    [0, 0],
    [50, 100],
    [100, 50],
    [[150, 100], 2]   // 带权重
]);
spline2.setDefaults();
Engine.addEntities(spline2);
```

**两种模式对比**：
- `setFitPoints(pts)` — 曲线必须经过每个点，适合已知路径
- `setControlPoints(pts)` — 控制点像磁铁拉曲线，支持权重，适合造型设计

### RayEnt / XLineEnt - 射线 / 构造线

```javascript
const { RayEnt, XLineEnt, Engine } = vjcad;   // 类名是 XLineEnt（大写 L），不是 XlineEnt

// 射线（从起点沿角度无限延伸）——构造签名是 (startPoint, rayAngle弧度)，不是方向点
const ray = new RayEnt([0, 0], Math.PI / 4);  // 起点, 45°
ray.setDefaults();
Engine.addEntities(ray);

// 构造线（向两个方向无限延伸）——(basePoint, angle弧度)
const xline = new XLineEnt([50, 50], 0);      // 通过点, 0° 水平线
xline.setDefaults();
Engine.addEntities(xline);
```

### DotEnt - 点

```javascript
const { DotEnt, Engine } = vjcad;

const dot = new DotEnt([50, 50]);
dot.setDefaults();
Engine.addEntities(dot);
```

### SolidEnt - 实体填充

```javascript
const { SolidEnt, Engine } = vjcad;

// 三角形填充
const solid = new SolidEnt([0, 0], [100, 0], [50, 80]);
solid.setDefaults();
solid.color = 1;
Engine.addEntities(solid);

// 四边形填充：按周边顺序 p1→p2→p3→p4 绘制（不是 AutoCAD SOLID 的 1-2-4-3 "Z" 序）
const solid2 = new SolidEnt([0, 0], [100, 0], [100, 80], [0, 80]);
solid2.setDefaults();
Engine.addEntities(solid2);
```

---

## 通用属性

所有实体都支持以下属性：

| 属性 | 说明 | 示例 |
|------|------|------|
| `color` | 颜色索引 | 1红 2黄 3绿 4青 5蓝 6洋红 7白, 256随层 |
| `layer` | 图层名 | `"图层A"` |
| `lineType` | 线型名 | `"CONTINUOUS"`, `"HIDDEN"`, `"CENTER"` |
| `lineTypeScale` | 线型比例 | `1.0` |
| `lineWeight` | 线宽 | `15` (0.15mm), `-1` 随层 |

## 通用方法

| 方法 | 说明 |
|------|------|
| `setDefaults()` | 应用系统默认属性（**必须在设置其他属性前调用**）|
| `boundingBox()` | 获取边界框 |
| `clone()` | 创建副本 |
| `move(from, to)` | 移动 |
| `rotate(center, angle)` | 旋转（弧度）|
| `scale(center, factor)` | 缩放 |
| `mirror(p1, p2)` | 镜像 |
