offset-trim-extend
本文回答:偏移 / 裁剪 / 延长是 vjcad 三大实体级算法。命令版用
OFFSET / TRIM / EXTEND;编程版可直接调几何工具或自行实现,详见vjcad/example/geometry/10offset.js / 11trim.js / 12extend.js。
一、偏移(OFFSET)
命令: OFFSET
指定偏移距离 <上次值>: <输入距离>
选择要偏移的对象: <选择对象>
指定要偏移的那一侧上的点: <点击方向>
代码触发:
Engine.editor.executerWithOp('OFFSET');
// 或脚本
Engine.editor.automate(`OFFSET\n10\n... `);
MCP 参考:vjcad/doc/edit/edit-commands.md。
自定义偏移命令的完整模板见
vjcad/doc/selection/entity-selection.md中 "OffsetCommand 完整命令示例(偏移命令-循环选择)"。该模板用Engine.OFFSETDIST系统变量保存上次距离,用getEntity循环选实体并getPoint选偏移方向。
二、裁剪(TRIM)
vjcad/example/geometry/11trim.js 演示基于交点的实体裁剪算法(按选中边界 + 选中目标 → 求交点 → 在 pickPoint 那段截断)。
完整自定义命令骨架(来自文档):
class TrimCommand {
async main() {
Engine.undoManager.start_undoMark();
try {
// 1. 选边界
const bRes = await getSelections(new SelectionInputOptions());
if (bRes.status !== InputStatusEnum.OK) return;
const boundaries = bRes.value;
// 2. 循环选要修剪的实体
Engine.pcanvas.highLightEntities(boundaries);
while (true) {
const r = await getEntity(new SelectionSetInputOptions('选择要修剪的对象:'));
if (r.status === InputStatusEnum.OK) {
this.trimEntity(r.pickedEntity, r.pickedPoint, boundaries);
Engine.pcanvas.regen();
} else if (r.status === InputStatusEnum.EnterOrSpace ||
r.status === InputStatusEnum.Cancel) {
break;
}
}
} finally {
Engine.undoManager.end_undoMark();
Engine.pcanvas.clearHighLight();
}
}
trimEntity(ent, pickPt, boundaries) {
if (ent.type === 'LINE') this.trimLine(ent, pickPt, boundaries);
else if (ent.type === 'ARC') this.trimArc(ent, pickPt, boundaries);
// ... 其他类型按需扩展
}
}
MCP 参考:vjcad/doc/selection/entity-selection.md、vjcad/example/geometry/11trim.js。
命令版
TRIM可直接用Engine.editor.executerWithOp('TRIM')触发。
三、延长(EXTEND)
vjcad/example/geometry/12extend.js 演示了实体延长到边界的算法。流程相似:选边界 + 选要延长的目标 → 求交点 → 把端点替换为该交点。
Engine.editor.executerWithOp('EXTEND');
四、几何工具的相关核心
| 算法 | 工具 |
|---|---|
| 求交点(裁剪 / 延长依赖) | GeometryCalculator.{A}To{B} (intersection) |
| 边界框粗筛(性能) | entity.boundingBox() + 简单矩形相交 |
| 空间索引(百万级) | SpatialIndex(spatial-index) |
| 偏移端点判断(用哪一侧) | GeometryCalculator.witchSidePointToLine(lineStart, lineEnd, point)(distance-angle) |
反例
OFFSET写脚本时把距离单位当 mm:vjcad 的"偏移距离"是绘图单位,与文档单位一致。TRIM/EXTEND算法没有对自定义实体做分支:对CustomEntityBase的实体先转成内嵌真实实体(buildNestEnts())再处理。- 一次性删除 trim 后的旧实体:应用
Engine.eraseEntities+ 新实体Engine.addEntities,外加一次regen。
参考(官方文档 MCP)
- 文档:
vjcad/doc/edit/edit-commands.md、vjcad/doc/selection/entity-selection.md、vjcad/doc/geometry/calculations.md - 示例:
vjcad/example/geometry/10offset.js、11trim.js、12extend.js