Skip to content
On this page

测量圆

下面我们将介绍如何利用 mxcad 插件实现在CAD图纸中测量圆的功能,该功能中用户点击目标圆对象将自动标记出这个圆的半径、面积值和周长值,同时用户可以自定义选择标注文字的位置。测量圆功能能够帮助用户快速掌握目标圆对象的数据信息,方便统计工程量。

功能实现

  1. 实现自定义圆标注类

为了方便后期管理与修改标注,我们可以通过继承 McDbCustomEntity 自定义实体类来扩展实现圆标注类。其中,在 mxcad 中圆对象对应的实体类为 McDbCircle ,该类提供了获取或设置圆相关信息的属性或方法,我们可以根据我们的功能需求去选择调用。在测量圆功能中,我们需要获取圆对象的半径、面积与周长,因此我们可以调用 McDbCircle.radius 属性获取圆半径,McDbCircle.getArea() 方法或直接计算来获取圆面积,以及 McDbCircle.getLength() 方法获取圆周长。

然后,我们可以利用 McDbMText 构造测量信息多文本对象,将圆的标注信息绘制在页面中。

ts
// 自定义圆标注类
class McDbTestMeasuringCircle extends McDbCustomEntity {
    // 定义McDbTestMeasuringCircle内部的点对象 
    // 圆心
    private center: McGePoint3d = new McGePoint3d();
    // 标注点
    private position: McGePoint3d = new McGePoint3d();
    // 圆半径
    private radius: number;
    // 构造函数
    constructor(imp?: any) {
        super(imp);
    }
    // 创建函数
    public create(imp: any) {
        return new McDbTestMeasuringCircle(imp)
    }
    // 获取类名
    public getTypeName(): string {
        return "McDbTestMeasuringCircle";
    }
    //设置或获取圆半径
    public set circleRadius(val: number) {
        this.radius = val;
    }
    public get circleRadius(): number {
        return this.radius;
    }
    // 读取自定义实体数据center、position、radius
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.center = filter.readPoint("center").val;
        this.position = filter.readPoint("position").val;
        this.radius = filter.readDouble("radius").val;
        return true;
    }
    // 写入自定义实体数据center、position、radius
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("center", this.center);
        filter.writePoint("position", this.position);
        filter.writeDouble("radius", this.radius);
        return true;
    }

    // 移动自定义对象的夹点
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        this.position.x += dXOffset;
        this.position.y += dYOffset;
        this.position.z += dZOffset;
    };
    // 获取自定义对象的夹点
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray()
        ret.append(this.position);
        return ret;
    };
    // 绘制实体
    public worldDraw(draw: MxCADWorldDraw): void {
        // 绘制标注圆与标注信息
        const circle = new McDbCircle();
        circle.center = this.center;
        circle.radius = this.radius;
        const length = circle.getLength().val;
        const radius = circle.radius;
        const area = Math.PI * radius * radius;

        const mText = new McDbMText();
        mText.contents = `半径:${radius.toFixed(2)} \\P 周长:${length.toFixed(2)} \\P 面积:${area.toFixed(2)}`
        mText.textHeight = radius / 6;
        mText.attachment = McDb.AttachmentPoint.kMiddleCenter;
        mText.location = this.position;
        mText.trueColor = circle.trueColor = this.trueColor;
        draw.drawEntity(mText);
        draw.drawEntity(circle);
    }
    // 设置pt1
    public setCenter(pt: McGePoint3d) {
        this.assertWrite();
        this.center = pt.clone();
    }
    // 获取pt1
    public getCenter() {
        return this.center;
    }
    // 获取position
    public setPosition(pt: McGePoint3d) {
        this.assertWrite();
        this.position = pt.clone();
    }
    // 获取position
    public getPosition() {
        return this.position;
    }
}
  1. 注册自定义类信息
ts
new McDbTestMeasuringCircle().rxInit();
  1. 编写方法,调用 McDbTestMeasuringCircle 自定义圆标注类实现测量圆功能
  • 获取目标圆对象,得到相关数据信息

我们可以利用选择实体对象 MxCADUiPrEntity() 根据用户鼠标点击的坐标得到对应的实体,其中我们需要只选择圆对象,因此,我们再调用 MxCADResbuf() 为选择实体对象设置过滤器来过滤出目标实体。

ts
// 选择实体对象
const getEnt = new MxCADUiPrEntity();
// 设置提示信息
getEnt.setMessage("请选择一个圆对象");
// 设置过滤器
const filter = new MxCADResbuf([DxfCode.kEntityType, "CIRCLE"]);
getEnt.setFilter(filter);
// entId过滤选择后的圆实体对象ID
const entId = await getEnt.go();
if (!entId.id) return;
// 获取圆相关信息
const circle = entId.getMcDbEntity() as McDbCircle;
const mCircle = new McDbTestMeasuringCircle();
mCircle.setCenter(circle.center);
mCircle.circleRadius = circle.radius;
  • 指定标注点并绘制圆标注对象

我们可以利用 MxCADUiPrPoint 取点对象在页面中交互取点。在取点过程中,我们可以通过 MxCADUiPrPoint.setUserDraw() 方法动态绘制标注对象,使用户更加直观的观察到标注对象的位置变化。

ts
// 设置取点对象
const getPt = new MxCADUiPrPoint();
// 设置提示信息
getPt.setMessage('请指定文字位置');
// 动态绘制
getPt.setUserDraw((pt, pw) => {
    pw.setColor(0xFF0000);
    mCircle.setPosition(pt);
    pw.drawMcDbEntity(mCircle);
});
const point = await getPt.go();
if (!point) return;
// 设置标注文本位置
mCircle.setPosition(point);
// 设置圆标注对象颜色
mCircle.trueColor = new McCmColor(255, 0, 0)
const mxcad = MxCpp.getCurrentMxCAD();
// 绘制圆标注对象
mxcad.drawEntity(mCircle);

功能实践

实践效果如下:

  • 点击测量圆按钮,执行测量圆方法
  • 选中目标圆对象
  • 设置标注点位置
  • 成功绘制测量标注内容