line-polyline
本文回答:
LineEnt直线和PolylineEnt多段线 —— 创建、bulge 弧段、双线 dline、闭合、编辑。
一、LineEnt(直线段)
创建
const line = new vjmapext.LineEnt([x1, y1], [x2, y2]);
line.color = 0xff0000;
line.lineWidth = 2;
mapcadLayer.addEntity(line);
关键属性
| 属性 | 类型 |
|---|---|
startPoint |
Point2D |
endPoint |
Point2D |
midPoint |
只读 getter(没有 length/angle 属性,要自己算:startPoint.distanceTo(endPoint) / Math.atan2(dy,dx)) |
修改
line.startPoint = new Point2D(10, 10);
line.endPoint.x = 200;
line.changed();
场景
- 网格参考线 / 坐标轴
- 连接点(配合
PointEnt显示节点) - 配合标注、引线、扉页
二、PolylineEnt(多段线)
创建
// 折线
const poly = new vjmapext.PolylineEnt([
[0, 0], [100, 0], [100, 100], [200, 100]
]);
// 闭合多边形:最后一个参数 true
const rect = new vjmapext.PolylineEnt([
[0, 0], [100, 0], [100, 50], [0, 50]
], true);
rect.fillColor = 0x4488ff;
rect.fillOpacity = 0.3;
mapcadLayer.addEntity(rect);
关键属性
| 属性 | 说明 |
|---|---|
bulgePoints |
BulgePoint[] = {point: Point2D, bulge: number}——顶点和 bulge 都在这,没有独立 points/bulges 数组 |
isClosed |
是否闭合(字段名是 isClosed 不是 closed) |
vertices |
只读 getter,返回 Point2D[]——数组是新的,但 Point2D 是实体内部引用(改坐标会影响实体,改完仍需 changed()) |
addVertex(point, bulge?) |
追加顶点(内部已调 changed()) |
fillColor / fillOpacity / borderOpacity |
填充(闭合时生效),fillColor=-1 时用 color 填充 |
lineWidth |
默认线宽(继承 EntityBase) |
没有 widths 属性——1.0.1 不支持逐段线宽。
bulge 弧段(PLINE 精髓)
bulge = tan(θ/4),θ 为弧段包含角。
| bulge | 弧形 |
|---|---|
| 0 | 直线 |
| 1 | 半圆(θ = 180°) |
| 0.414 | 四分之一圆 |
| -1 | 反向半圆 |
const arcPoly = new vjmapext.PolylineEnt([
[0, 0], [100, 0], [100, 100], [0, 100]
], true);
// 第 1、3 段带弧:bulge 写在每个顶点的 bulgePoints[i].bulge 上
[0.5, 0, -0.5, 0].forEach((b, i) => { arcPoly.bulgePoints[i].bulge = b; });
arcPoly.changed();
bulge 弧段顶点
const pl = new vjmapext.PolylineEnt([[0, 0], [100, 50]], true);
pl.bulgePoints = [
{ point: new vjmapext.Point2D(0, 0), bulge: 0.5 },
{ point: new vjmapext.Point2D(100, 50), bulge: 0 }
];
pl.changed();
BulgePoint = { point: Point2D, bulge: number };bulge 为弧凸度(0 = 直线段)。
三、双线(DLINE 命令)
双线没有独立实体类,由 DLINE 命令或工具函数生成一对平行 LineEnt:
mapcadLayer.executeCommand('DLINE'); // 交互式绘制(内部会问宽度)
// 程序化:中心线 + 宽度 → 两侧端点
// 方式一:自己算两侧端点,返回 { startPt1, startPt2, endPt1, endPt2 }
const pts = vjmapext.calculateDoubleLinePoints(
new vjmapext.Point2D(0, 0), new vjmapext.Point2D(500, 0), 20
);
mapcadLayer.addEntity(new vjmapext.LineEnt(pts.startPt1, pts.endPt1));
mapcadLayer.addEntity(new vjmapext.LineEnt(pts.startPt2, pts.endPt2));
// 方式二:createDoubleLineSegment(startPt, endPt, width, prevLine1?, prevLine2?, miterLimit?)
// 返回 { line1, line2, bevelLine? }——传入前一段时拐角在 miterLimit 内用尖角,否则给斜角补边
const seg = vjmapext.createDoubleLineSegment(
new vjmapext.Point2D(0, 0), new vjmapext.Point2D(500, 0), 20
);
mapcadLayer.addEntity(seg.line1);
mapcadLayer.addEntity(seg.line2);
if (seg.bevelLine) mapcadLayer.addEntity(seg.bevelLine);
// 端头封口:createDoubleButtCap / createDoubleSquareCap / createDoubleRoundCap;闭合用 closeDoubleLineSegment
四、生成常用形状
圆角矩形
function roundRect(x, y, w, h, r) {
const pts = [
[x + r, y], [x + w - r, y],
[x + w, y + r], [x + w, y + h - r],
[x + w - r, y + h], [x + r, y + h],
[x, y + h - r], [x, y + r]
];
const poly = new vjmapext.PolylineEnt(pts, true);
// 每条短边(角)加 0.414 的 bulge(bulge 在 bulgePoints[i].bulge 上)
const bs = [0, 0.414, 0, 0.414, 0, 0.414, 0, 0.414];
poly.bulgePoints.forEach((bp, i) => { if (bs[i] != null) bp.bulge = bs[i]; });
return poly;
}
正多边形
function regularPolygon(cx, cy, radius, sides) {
const pts = [];
for (let i = 0; i < sides; i++) {
const a = (i / sides) * Math.PI * 2 - Math.PI / 2;
pts.push([cx + radius * Math.cos(a), cy + radius * Math.sin(a)]);
}
return new vjmapext.PolylineEnt(pts, true);
}
五、查询几何
poly.boundingBox(); // [minX, minY, maxX, maxY]——BBox 是 4 元素数组,不是 {min,max}
// 总长 / 面积 / 取点等 SDK 未直接提供,用 vertices 自算:
const vs = poly.vertices;
let len = 0;
for (let i = 1; i < vs.length; i++) len += vs[i].distanceTo(vs[i - 1]);
六、交互编辑
默认 editable = true,选中后显示夹点(getGripPoints() / gripEdit()):
- LineEnt:
start/end端点夹点拖动改端点;mid中点夹点拖动平移整条线 - PolylineEnt:顶点夹点(key 为索引
0..n-1)拖动改该顶点;mid_i段中点夹点拖动平移该段(相邻两顶点一起动)
注意:夹点没有"添加顶点"和"调 bulge"的操作——增顶点用 addVertex()(或属性面板 vertex-list 的插入),调 bulge 直接改 bulgePoints[i].bulge。
禁用:
line.editable = false;
详见 drawing/grip。
七、性能
| 场景 | 推荐 |
|---|---|
| < 1000 段的独立线段 | LineEnt 数组 |
| 连续折线(1 条 N 段) | PolylineEnt |
| 几十万级等值线 / 道路网 | 转 GeoJSON 走 primitive/line |
| 需要弧段 | PolylineEnt + bulgePoints |
八、常见坑
- PLINE 弧段 bulge 数量不对 →
bulgePoints长度 = 顶点数;第 i 项的bulge作用于"顶点 i → 顶点 i+1"段(闭合时末顶点段回首顶点)。 - 把
bulgePoints改成新数组/改了成员但没changed()→ 改引用和改值都要changed()(addVertex()内部已调,除外)。 - 以为不设 fillColor 就不填充 → 默认
-1的语义是"跟随color填充"(默认fillOpacity=0.2),不是不填充;想要别的填充色须显式设fillColor。 - LineEnt 当多段线用 → 直线只有 2 端点;多点必须
PolylineEnt。 - 期望 bulge 是弧度 / 角度 → 它是 tan(θ/4),不是角。