直线实体 (LineEnt)
大约 6 分钟
直线实体 (LineEnt)
LineEnt 是 WebCAD 中最基本的几何实体之一,表示由起点和终点确定的线段。
在线示例
| 示例 | 描述 | 链接 |
|---|---|---|
| 创建直线 | LineEnt 基本创建示例 | 在线演示{target="_blank"} |
| 直线属性 | 获取直线长度、角度、起终点 | 在线演示{target="_blank"} |
| 直线变换 | 移动、旋转、缩放、镜像、拉伸操作 | 在线演示{target="_blank"} |
| 颜色设置 | 使用索引颜色和 RGB 真彩色创建直线 | 在线演示{target="_blank"} |
概述
直线是 CAD 中最基础的绘图元素,用于绘制边界、轮廓、辅助线等。LineEnt 继承自 EntityBase,提供了丰富的几何操作方法。
3D 坐标支持
直线的 Z 坐标存储在 Point2D.z 属性中。通过 startPoint.z 和 endPoint.z 访问和修改 Z 值,或使用 startPointZ / endPointZ 便捷属性。
构造函数
import { LineEnt, Point2D } from 'vjcad';
// 简化写法(推荐)
const line1 = new LineEnt([0, 0], [100, 100]);
// Point2D 写法
const line2 = new LineEnt(
new Point2D(0, 0),
new Point2D(100, 100)
);
// 带颜色的构造
const line3 = new LineEnt([0, 0], [100, 0], 1); // 颜色索引(1=红色)
// 带 Z 坐标的 3D 直线
const line4 = new LineEnt([0, 0, 0], [100, 100, 50]);
// 默认构造(起点原点,终点(1,0))
const line5 = new LineEnt();简化写法
构造函数支持 [x, y] 或 [x, y, z] 数组形式的点坐标,避免每次都写 new Point2D(...)。
属性
几何属性
| 属性 | 类型 | 读写 | 说明 |
|---|---|---|---|
startPoint | Point2D | 读写 | 直线起点坐标(含可选 z) |
endPoint | Point2D | 读写 | 直线终点坐标(含可选 z) |
startPointZ | number | 读写 | 起点 Z 坐标便捷属性(等同于 startPoint.z) |
endPointZ | number | 读写 | 终点 Z 坐标便捷属性(等同于 endPoint.z) |
计算属性(只读)
| 属性 | 类型 | 说明 |
|---|---|---|
Length | number | 直线长度 |
angle | number | 直线角度(弧度,0-2π) |
midPoint | Point2D | 直线中点 |
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
// 获取几何属性
console.log('起点:', line.startPoint); // Point2D(0, 0)
console.log('终点:', line.endPoint); // Point2D(100, 100)
console.log('长度:', line.Length); // 141.42...
console.log('角度(弧度):', line.angle); // 0.785... (45°)
console.log('角度(度):', line.angle * 180 / Math.PI); // 45
console.log('中点:', line.midPoint); // Point2D(50, 50)
// 修改几何属性
line.startPoint = new Point2D(10, 10);
line.endPoint.x = 200; // 可以直接修改坐标分量
line.endPoint.y = 200;方法
几何变换
所有几何变换方法都支持 PointInput 类型参数,可以使用 [x, y] 数组或 Point2D 对象。
move() - 移动
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt([0, 0], [100, 100]);
// 简化写法(推荐)
line.move([0, 0], [50, 50]); // 整条线平移 (50, 50)
console.log(line.startPoint); // Point2D(50, 50)
console.log(line.endPoint); // Point2D(150, 150)rotate() - 旋转
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt([0, 0], [100, 0]);
// 简化写法(推荐)
line.rotate([0, 0], Math.PI / 2); // 绕原点旋转 90 度
console.log(line.startPoint); // Point2D(0, 0)
console.log(line.endPoint); // Point2D(0, 100)
// 绕中点旋转 45 度
const midPoint = line.midPoint;
line.rotate(midPoint, Math.PI / 4);scale() - 缩放
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt([0, 0], [100, 0]);
// 简化写法(推荐)
line.scale([0, 0], 2); // 以原点为中心放大 2 倍
console.log(line.Length); // 200
// 以中点为中心缩小 50%
line.scale(line.midPoint, 0.5);mirror() - 镜像
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt([0, 0], [100, 100]);
// 简化写法(推荐)
line.mirror([0, 0], [100, 0]); // 沿 X 轴(Y=0)镜像
console.log(line.startPoint); // Point2D(0, 0)
console.log(line.endPoint); // Point2D(100, -100)
// 沿任意直线镜像
line.mirror([0, 0], [1, 1]); // 沿 45° 线镜像编辑操作
reversePoint() - 反转方向
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
console.log('反转前角度:', line.angle * 180 / Math.PI); // 45°
line.reversePoint(); // 交换起点和终点
console.log('反转后角度:', line.angle * 180 / Math.PI); // 225°trimFrontAtDist() - 从起点修剪
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 0));
console.log('原始长度:', line.Length); // 100
// 从起点修剪 30 的距离
line.trimFrontAtDist(30);
console.log('修剪后起点:', line.startPoint); // Point2D(30, 0)
console.log('修剪后长度:', line.Length); // 70trimBackAtDist() - 从终点修剪
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 0));
// 从终点修剪 20 的距离
line.trimBackAtDist(20);
console.log('修剪后终点:', line.endPoint); // Point2D(80, 0)
console.log('修剪后长度:', line.Length); // 80夹点编辑
gripEdit() 方法用于处理夹点拖动编辑。
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
// 夹点类型: "start" | "end" | "mid"
// 移动起点夹点
line.gripEdit(new Point2D(10, 10), "start");
console.log(line.startPoint); // Point2D(10, 10)
// 移动终点夹点
line.gripEdit(new Point2D(200, 200), "end");
console.log(line.endPoint); // Point2D(200, 200)
// 移动中点夹点(整体移动)
line.gripEdit(new Point2D(150, 150), "mid");
// 整条线平移,保持长度和角度不变边界框
import { LineEnt, Point2D, CoordinateSystemType } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
// 获取 WCS 边界框(默认)
const wcsBBox = line.boundingBox();
console.log('最小点:', wcsBBox.pt1); // Point2D(0, 0)
console.log('最大点:', wcsBBox.pt2); // Point2D(100, 100)
// 获取 DCS 边界框(屏幕坐标)
const dcsBBox = line.boundingBox(CoordinateSystemType.DCS);克隆
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
line.setDefaults();
line.color = 1;
// 创建深拷贝
const lineCopy = line.clone();
// 修改副本不影响原实体
lineCopy.color = 3;
lineCopy.move([0, 0], [50, 0]);
console.log(line.color); // 1
console.log(lineCopy.color); // 3序列化
import { LineEnt, Point2D } from 'vjcad';
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
line.setDefaults();
// 导出为数据库格式(2D 直线)
const dbData = line.toDb();
console.log(dbData);
// {
// type: "LINE",
// layerId: "0",
// color: 256,
// startPoint: [0, 0],
// endPoint: [100, 100]
// }
// 带 Z 坐标的直线
line.startPoint.z = 10;
line.endPoint.z = 20;
const dbData3d = line.toDb();
console.log(dbData3d);
// {
// type: "LINE",
// startPoint: [0, 0, 10],
// endPoint: [100, 100, 20]
// ...
// }
// 从数据库格式恢复
const newLine = new LineEnt();
newLine.fromDb(dbData);完整示例
绘制十字线
import { Engine, LineEnt, Point2D } from 'vjcad';
function drawCrossHair(center: Point2D, size: number) {
const halfSize = size / 2;
// 水平线
const hLine = new LineEnt(
new Point2D(center.x - halfSize, center.y),
new Point2D(center.x + halfSize, center.y)
);
// 垂直线
const vLine = new LineEnt(
new Point2D(center.x, center.y - halfSize),
new Point2D(center.x, center.y + halfSize)
);
hLine.setDefaults();
vLine.setDefaults();
hLine.color = 1; // 红色
vLine.color = 1;
Engine.addEntities([hLine, vLine]);
}
drawCrossHair(new Point2D(100, 100), 50);绘制正多边形
import { Engine, LineEnt, Point2D } from 'vjcad';
function drawPolygon(center: Point2D, radius: number, sides: number) {
const lines: LineEnt[] = [];
const angleStep = (2 * Math.PI) / sides;
for (let i = 0; i < sides; i++) {
const angle1 = i * angleStep;
const angle2 = (i + 1) * angleStep;
const p1 = new Point2D(
center.x + radius * Math.cos(angle1),
center.y + radius * Math.sin(angle1)
);
const p2 = new Point2D(
center.x + radius * Math.cos(angle2),
center.y + radius * Math.sin(angle2)
);
const line = new LineEnt(p1, p2);
line.setDefaults();
lines.push(line);
}
Engine.addEntities(lines);
}
// 绘制正六边形
drawPolygon(new Point2D(100, 100), 50, 6);交互式绘制直线
import {
Engine,
LineEnt,
Point2D,
PointInputOptions,
InputStatusEnum
} from 'vjcad';
async function drawLineCommand() {
// 获取起点
const opt1 = new PointInputOptions("指定起点:");
const result1 = await Engine.getPoint(opt1);
if (result1.status !== InputStatusEnum.OK) return;
const startPoint = result1.value as Point2D;
// 获取终点(显示橡皮线)
const opt2 = new PointInputOptions("指定终点:");
opt2.basePoint = startPoint;
opt2.useBasePoint = true;
const result2 = await Engine.getPoint(opt2);
if (result2.status !== InputStatusEnum.OK) return;
const endPoint = result2.value as Point2D;
// 创建直线
const line = new LineEnt(startPoint, endPoint);
line.setDefaults();
// 添加到画布
Engine.addEntities(line);
// 输出信息
Engine.writeMessage(`直线已创建,长度: ${line.Length.toFixed(2)}`);
}常见问题
Q: 如何获取直线的方向向量?
const line = new LineEnt(new Point2D(0, 0), new Point2D(100, 100));
// 方向向量
const dx = line.endPoint.x - line.startPoint.x;
const dy = line.endPoint.y - line.startPoint.y;
// 单位方向向量
const length = line.Length;
const unitX = dx / length;
const unitY = dy / length;
console.log(`方向向量: (${unitX.toFixed(3)}, ${unitY.toFixed(3)})`);Q: 如何判断点是否在直线上?
import { LineEnt, Point2D } from 'vjcad';
function isPointOnLine(line: LineEnt, point: Point2D, tolerance: number = 0.001): boolean {
const d1 = distance(line.startPoint, point);
const d2 = distance(point, line.endPoint);
const lineLength = line.Length;
return Math.abs(d1 + d2 - lineLength) < tolerance;
}
function distance(p1: Point2D, p2: Point2D): number {
const dx = p2.x - p1.x;
const dy = p2.y - p1.y;
return Math.sqrt(dx * dx + dy * dy);
}Q: 如何延长直线?
import { LineEnt, Point2D } from 'vjcad';
function extendLine(line: LineEnt, extensionLength: number, fromEnd: boolean = true) {
const angle = line.angle;
if (fromEnd) {
// 从终点延长
line.endPoint = new Point2D(
line.endPoint.x + extensionLength * Math.cos(angle),
line.endPoint.y + extensionLength * Math.sin(angle)
);
} else {
// 从起点延长(反方向)
line.startPoint = new Point2D(
line.startPoint.x - extensionLength * Math.cos(angle),
line.startPoint.y - extensionLength * Math.sin(angle)
);
}
}下一步
- 圆实体 (CircleEnt) - 圆实体详解
- 圆弧实体 (ArcEnt) - 圆弧实体详解
- 多段线实体 (PolylineEnt) - 多段线实体详解