面域
面域(Region)是由一条或多条闭合边界轮廓围成的二维填充区域,常用于表达带有面积的平面图形。与普通曲线不同,面域记录的是"区域"而非"轮廓线",因此支持对多个区域做布尔运算、边界偏移、三角化等几何处理。我们可以通过实例化一个 McDbMxRegion() 对象创建面域。
点击 McDbMxRegion() 查看详细属性和方法说明。
创建面域
通过 addContour() 方法给面域添加一组点构成的边界轮廓,也可以通过 addEntityContour() 方法基于一个已有的曲线对象(如圆、多义线等)给面域添加边界轮廓,同一个面域可以添加多条边界轮廓。
点击 addContour() 、addEntityContour() 查看详细属性和方法说明。
import { MxCpp, McCmColor, McDbMxRegion, McDbCircle, McGePoint3d, McGePoint3dArray } from "mxcad"
const mxcad = MxCpp.getCurrentMxCAD()
// 通过一组点边界轮廓创建矩形面域
const region = new McDbMxRegion()
const points = new McGePoint3dArray()
points.append(new McGePoint3d(0, 0, 0))
points.append(new McGePoint3d(100, 0, 0))
points.append(new McGePoint3d(100, 80, 0))
points.append(new McGePoint3d(0, 80, 0))
region.addContour(points)
region.trueColor = new McCmColor(255, 0, 0)
mxcad.drawEntity(region)
// 基于一个圆对象创建圆形面域
const region_1 = new McDbMxRegion()
region_1.addEntityContour(new McDbCircle(250, 40, 0, 40))
region_1.trueColor = new McCmColor(0, 255, 0)
mxcad.drawEntity(region_1)布尔运算
booleanOption(type, other) 用于把当前面域与另一个面域 other 进行布尔运算,运算类型由 BooleanOptionType 指定。布尔运算会重新计算区域的覆盖范围,是面域最核心的几何操作,常用于合并零件、求公共区域、开孔挖槽等场景。四种运算的几何意义与实现效果如下:
| 运算类型 | 枚举值 | 几何意义 | 实现效果 |
|---|---|---|---|
| 并集 Union | 1 | 合并两个面域覆盖的全部区域,重叠部分只保留一次 | 把相邻或相交的多个区域拼成一个整体 |
| 交集 Intersection | 0 | 只保留两个面域重叠的公共部分 | 求公共区域,可用于裁剪、求重合面积 |
| 差集 Difference | 2 | 从当前面域中减去与 other 重叠的部分 | 在区域上开孔、挖槽、扣除(有方向性,是"当前面域 减 other") |
| 异或 Xor | 3 | 保留两个面域各自不重叠的部分,去掉公共重叠区域 | 求两个区域的对称差 |
需要注意,布尔运算的结果可能分裂成多个互不连通的区域(例如差集之后剩下的部分可能不连续),因此 booleanOption() 返回的是面域数组 McDbMxRegion[],需要遍历数组逐个绘制。此外,每种运算都建议使用全新的面域对象,避免上一次运算的结果影响下一次。
点击 booleanOption() 查看详细属性和方法说明。
import { MxCpp, McDbMxRegion, McDbCircle, McGePoint3d, McGePoint3dArray, McDb } from "mxcad"
const mxcad = MxCpp.getCurrentMxCAD()
// 构造一对部分重叠的面域:矩形 A 与圆形 B
function createPair() {
const regionA = new McDbMxRegion()
const pointsA = new McGePoint3dArray()
pointsA.append(new McGePoint3d(0, 0, 0))
pointsA.append(new McGePoint3d(100, 0, 0))
pointsA.append(new McGePoint3d(100, 80, 0))
pointsA.append(new McGePoint3d(0, 80, 0))
regionA.addContour(pointsA)
const regionB = new McDbMxRegion()
regionB.addEntityContour(new McDbCircle(100, 40, 0, 50))
return [regionA, regionB]
}
// 并集:合并 A、B 覆盖的全部区域
const [a1, b1] = createPair()
a1.booleanOption(McDb.BooleanOptionType.Union, b1).forEach(item => mxcad.drawEntity(item))
// 交集:只保留 A、B 重叠的公共部分
const [a2, b2] = createPair()
a2.booleanOption(McDb.BooleanOptionType.Intersection, b2).forEach(item => mxcad.drawEntity(item))
// 差集:从 A 中减去与 B 重叠的部分(A 减 B 与 B 减 A 结果不同)
const [a3, b3] = createPair()
a3.booleanOption(McDb.BooleanOptionType.Difference, b3).forEach(item => mxcad.drawEntity(item))
// 异或:保留 A、B 各自不重叠的部分,去掉公共区域
const [a4, b4] = createPair()
a4.booleanOption(McDb.BooleanOptionType.Xor, b4).forEach(item => mxcad.drawEntity(item))边界偏移
inflatePaths(delta, joinType?, endType?) 用于把面域的边界整体向内或向外平移,生成一个新的面域。其几何意义是对区域做"等距膨胀/收缩":delta 为偏移距离,正值使边界向外扩张、区域变大,负值使边界向内收缩、区域变小。这一运算常用于生成轮廓的等距偏移线、预留加工余量、做区域缓冲(buffer)等。
其中 joinType 控制边界拐角处的连接方式(如直角、斜接、圆角),默认值为 2;endType 控制边界端点的闭合方式,默认值为 0。两者均为数值类型,具体取值含义可参考 API 文档。
点击 inflatePaths() 查看详细属性和方法说明。
import { MxCpp, McCmColor, McDbMxRegion, McGePoint3d, McGePoint3dArray } from "mxcad"
const mxcad = MxCpp.getCurrentMxCAD()
// 创建一个矩形面域
const region = new McDbMxRegion()
const points = new McGePoint3dArray()
points.append(new McGePoint3d(0, 0, 0))
points.append(new McGePoint3d(100, 0, 0))
points.append(new McGePoint3d(100, 80, 0))
points.append(new McGePoint3d(0, 80, 0))
region.addContour(points)
region.trueColor = new McCmColor(255, 0, 0)
mxcad.drawEntity(region)
// 边界向外扩张 10,得到一个放大后的新面域
const inflated = region.inflatePaths(10)
inflated.trueColor = new McCmColor(255, 233, 0)
mxcad.drawEntity(inflated)
// 边界向内收缩 10,得到一个缩小后的新面域
const shrunk = region.inflatePaths(-10)
shrunk.trueColor = new McCmColor(0, 255, 0)
mxcad.drawEntity(shrunk)三角化
triangulate(useDelaunay?) 用于把面域剖分成一组三角形,返回一个新的面域。其几何意义是把任意形状的多边形区域离散成三角形网格:当 useDelaunay 为 true(默认)时采用德劳内(Delaunay)三角剖分,它会尽量让每个三角形都不"狭长",从而得到质量更均匀的网格。三角化是渲染填充、网格划分、有限元前处理等场景的常见前置步骤。
点击 triangulate() 查看详细属性和方法说明。
import { MxCpp, McCmColor, McDbMxRegion, McDbCircle } from "mxcad"
const mxcad = MxCpp.getCurrentMxCAD()
// 基于一个圆创建面域
const region = new McDbMxRegion()
region.addEntityContour(new McDbCircle(0, 0, 0, 50))
region.trueColor = new McCmColor(255, 0, 0)
mxcad.drawEntity(region)
// 对圆形面域做德劳内三角剖分,得到由三角形组成的新面域
const triangulated = region.triangulate(true)
triangulated.trueColor = new McCmColor(0, 128, 255)
mxcad.drawEntity(triangulated)边界与面积查询
面域还提供了一组查询与数据管理方法:getContourCount() 得到边界轮廓的数目,getContour(index) 得到指定序号的边界坐标,getArea() 计算面域面积(返回 { ret, val },ret 表示是否成功、val 为面积值),getBoundingBox() 得到面域的最小外包矩形。此外可以用 isEmpty() 判断面域数据是否为空、clearData() 清除面域数据、copyData() 从另一个面域拷贝数据。
点击 getContourCount() 、getContour() 、getArea() 、getBoundingBox() 查看详细属性和方法说明。
import { MxCpp, McDbMxRegion, McGePoint3d, McGePoint3dArray } from "mxcad"
const mxcad = MxCpp.getCurrentMxCAD()
const region = new McDbMxRegion()
const points = new McGePoint3dArray()
points.append(new McGePoint3d(0, 0, 0))
points.append(new McGePoint3d(100, 0, 0))
points.append(new McGePoint3d(100, 80, 0))
points.append(new McGePoint3d(0, 80, 0))
region.addContour(points)
// 边界轮廓数目
console.log("边界数目:", region.getContourCount())
// 第 0 条边界的坐标点
console.log("边界坐标:", region.getContour(0))
// 面积
const area = region.getArea()
if (area.ret) console.log("面积:", area.val)
// 最小外包矩形
const box = region.getBoundingBox()
if (box.ret) console.log("外包矩形:", box.minPt, box.maxPt)