填充实体 (HatchEnt)
大约 4 分钟
填充实体 (HatchEnt)
HatchEnt 表示 CAD 中的填充实体,用于在闭合区域内填充图案或实心颜色。
概述
填充可以使用预定义图案、实心颜色或渐变色。填充需要一个或多个闭合边界来定义填充区域。边界通过 Edge 和 Edges 类定义,支持多段线、圆和椭圆类型。
构造函数
import { HatchEnt } from 'vjcad';
// 创建填充实体
const hatch = new HatchEnt();
// 设置图案
hatch.patternName = 'ANSI31';
hatch.patternScale = 1.0;
hatch.patternAngle = 0;
// 设置边界后调用 setDefaults
hatch.setLoops(edges);
hatch.setDefaults();属性
| 属性 | 类型 | 说明 |
|---|---|---|
patternName | string | 填充图案名称 |
patternScale | number | 图案比例 |
patternAngle | number | 图案旋转角度(弧度) |
patternCross | boolean | 是否交叉图案 |
loops | Edges | 边界循环集合 |
边界类型 (EdgeType)
| 类型 | 说明 |
|---|---|
EdgeType.Polyline | 多段线边界 |
EdgeType.Circle | 圆形边界 |
EdgeType.Ellipse | 椭圆边界 |
常用图案
| 图案名称 | 说明 |
|---|---|
SOLID | 实心填充 |
ANSI31 | 45° 斜线 |
ANSI32 | 双斜线 |
ANSI37 | 交叉线 |
JIS_LC_20 | JIS 图案 |
PAT 图案格式说明
PAT 格式是 AutoCAD 标准的填充图案定义格式,每个图案由多行定义组成:
头部行
*图案名称,图案描述- 以
*开头 - 图案名称和描述用逗号分隔
线定义行
角度,X原点,Y原点,deltaX,deltaY[,线型定义...]| 参数 | 说明 |
|---|---|
| 角度 | 线条绘制方向(度),0=水平向右,90=垂直向上 |
| X原点 | 第一条线的 X 起点坐标 |
| Y原点 | 第一条线的 Y 起点坐标 |
| deltaX | 沿线条方向的偏移量(用于虚线等线型) |
| deltaY | 垂直于线条方向的偏移量(行间距) |
| 线型定义 | 可选的虚线模式:正数=实线段,负数=空隙,0=点 |
格式示例
简单 45° 斜线:
45,0,0,0,1- 角度 45°,起点 (0,0),deltaY=1(行间距),连续实线
带虚线的水平线:
0,0,0,4,4,2,-1,0.5,-0.5- 水平线,起点 (0,0),deltaX=4, deltaY=4
- 线型:实线 2,空隙 1,点,空隙 0.5
自定义图案
注册自定义图案
import { Engine } from 'vjcad';
// 图案定义字符串(PAT 格式)
const patString = `*草坪或沼泽,草坪或沼泽
0,1.2,0.08,4,4,0.6,-0.12,0.16,-0.12,0.6,-2.4
0,1,0.2,4,4,0.4,-0.3,0.6,-0.3,0.4,-2
90,0.8,2.6,4,4,0.36,-3.64
90,2,0.2,4,4,0.4,-3.6`;
// 解析 PAT 格式字符串
function parsePatternString(patString) {
const lines = patString.trim().split('\n');
const headerMatch = lines[0].match(/^\*([^,]+),(.*)$/);
if (!headerMatch) throw new Error(`无效的图案头部`);
const name = headerMatch[1].trim();
const description = headerMatch[2].trim();
const patternLines = [];
for (let i = 1; i < lines.length; i++) {
const line = lines[i].trim();
if (!line || line.startsWith(';')) continue;
const parts = line.split(',').map(p => parseFloat(p.trim()));
patternLines.push({
angle: parts[0],
xOrigin: parts[1],
yOrigin: parts[2],
deltaX: parts[3],
deltaY: parts[4],
dashes: parts.slice(5)
});
}
return { name, description, lines: patternLines };
}
// 注册到 PatternManager
const patternDef = parsePatternString(patString);
Engine.patternManager.registerPattern(patternDef, "custom");
// 使用自定义图案
const hatch = new HatchEnt();
hatch.patternName = "草坪或沼泽";
hatch.patternScale = 10;自动计算比例
使用 calculateHatchPatternScale 函数根据边界大小自动计算合适的填充比例,避免填充太密或太稀疏。
import { Engine, HatchEnt, PolylineEnt, Edge, Edges, EdgeType, calculateHatchPatternScale } from 'vjcad';
// 创建边界
const boundary = new PolylineEnt();
boundary.setPoints([[0, 0], [200, 0], [200, 150], [0, 150]]);
boundary.isClosed = true;
boundary.setDefaults();
// 计算边界大小
const bbox = boundary.boundingBox();
const boundsSize = Math.max(bbox.maxX - bbox.minX, bbox.maxY - bbox.minY);
// 自动计算比例
const patternName = "ANSI31";
const patternDef = Engine.patternManager.getPattern(patternName);
const autoScale = calculateHatchPatternScale(boundsSize, patternName, patternDef);
// 创建填充
const hatch = new HatchEnt();
hatch.patternName = patternName;
hatch.patternScale = autoScale; // 使用自动计算的比例
const edges = new Edges();
const edge = new Edge();
edge.edgeType = EdgeType.Polyline;
edge.bulgePoints = boundary.bulgePoints.clone();
edges.add(edge);
hatch.setLoops(edges);
hatch.setDefaults();
Engine.addEntities([boundary, hatch]);calculateHatchPatternScale 参数
| 参数 | 类型 | 说明 |
|---|---|---|
boundsSize | number | 边界的最大尺寸(宽高中的较大值) |
patternName | string | 图案名称,"SOLID" 直接返回 1 |
patternDef | object | 图案定义(可选,若不提供则从 PatternManager 获取) |
getPatternUnitSize 函数
获取图案重复单元的大约尺寸,用于自定义比例计算:
import { getPatternUnitSize } from 'vjcad';
const patternDef = Engine.patternManager.getPattern("ANSI31");
const unitSize = getPatternUnitSize(patternDef);
console.log(`图案单元大小: ${unitSize}`);示例
多段线边界填充
import { Engine, HatchEnt, PolylineEnt, Edge, Edges, EdgeType } from 'vjcad';
// 创建多段线边界
const polyline = new PolylineEnt();
polyline.setPoints([
[0, 0],
[60, 0],
[60, 50],
[30, 70],
[0, 50]
]);
polyline.isClosed = true;
polyline.setDefaults();
// 创建填充
const hatch = new HatchEnt();
hatch.patternName = 'ANSI31';
hatch.patternScale = 2;
// 从多段线创建边界
const edges = new Edges();
const edge = new Edge();
edge.edgeType = EdgeType.Polyline;
edge.bulgePoints = polyline.bulgePoints.clone();
edges.add(edge);
hatch.setLoops(edges);
hatch.setDefaults();
hatch.color = 1;
Engine.addEntities([polyline, hatch]);圆形边界填充
import { Engine, HatchEnt, CircleEnt, Edge, Edges, EdgeType } from 'vjcad';
// 创建圆形边界
const circle = new CircleEnt([120, 35], 30);
circle.setDefaults();
// 创建实心填充
const hatch = new HatchEnt();
hatch.patternName = 'SOLID';
// 从圆创建边界(setLoops 自动处理 regenBulgePoints 和闭合)
const edges = new Edges();
const edge = new Edge();
edge.edgeType = EdgeType.Circle;
edge.center = circle.center.clone();
edge.radius = circle.radius;
edges.add(edge);
hatch.setLoops(edges);
hatch.setDefaults();
hatch.color = 3;
Engine.addEntities([circle, hatch]);带孔填充(多边界)
import { Engine, HatchEnt, PolylineEnt, CircleEnt, Edge, Edges, EdgeType } from 'vjcad';
// 外边界(矩形)
const outerRect = new PolylineEnt();
outerRect.setPoints([
[180, 0],
[260, 0],
[260, 70],
[180, 70]
]);
outerRect.isClosed = true;
outerRect.setDefaults();
// 内边界(圆形孔)
const innerCircle = new CircleEnt([220, 35], 15);
innerCircle.setDefaults();
// 创建填充
const hatch = new HatchEnt();
hatch.patternName = 'ANSI32';
hatch.patternScale = 2;
// 所有边界放入同一个 Edges 对象
const allEdges = new Edges();
// 外边界
const outerEdge = new Edge();
outerEdge.edgeType = EdgeType.Polyline;
outerEdge.bulgePoints = outerRect.bulgePoints.clone();
allEdges.add(outerEdge);
// 内边界(孔)
const innerEdge = new Edge();
innerEdge.edgeType = EdgeType.Circle;
innerEdge.center = innerCircle.center.clone();
innerEdge.radius = innerCircle.radius;
allEdges.add(innerEdge);
hatch.setLoops(allEdges);
hatch.setDefaults();
hatch.color = 5;
Engine.addEntities([outerRect, innerCircle, hatch]);方法
setLoops(edges: Edges)
设置边界循环。该方法会自动:
- 对
Circle和Ellipse类型的边界调用regenBulgePoints()生成凸度点 - 设置填充为闭合状态
hatch.setLoops(edges);setDefaults()
设置默认属性(图层、颜色等)。
regenLoop()
重新生成填充循环,当边界发生变化时调用。