在线CAD二次开发中动态交互式绘制星形的教程

前言

在 mxcad 中绘制星形,本质上还是绘制多段线,下面我们将介绍如何使用mxcad中的多段线去绘制一个支持自定义大小与定点数的星形,实现一个动态交互式的绘制星形功能。

在线CAD功能DEMO:在线CAD梦想画图

基础准备

1. 搭建绘图环境,创建一个mxcad项目,具体操作请参考 mxcad | 快速入门

2. 在项目中添加命令行,实现功能的动态交互功能,具体操作请参考 mxcad | 命令行

绘制星形

1. 首先通过 mxcad 提供的获取用户输入整数的 MxCADUiPrInt()类来获取星形顶点数。

const starVert = new MxCADUiPrInt()
starVert.setMessage("\n请输入星形顶点数:")
const starNum = await starVert.go()
if (!starNum) return;

其命令行交互如下:

  1. 通过 mxcad 提供的获取用户UI交互取点的[MxCADUiPrPoint()]类来获取星形圆心所在点的位置。

    const getCenter = new MxCADUiPrPoint()
    getCenter.setMessage("\n指定星形中心点:")
    const center = await getCenter.go()
    if (!center) return;
  2. 利用 mxcad 的动态绘制功能,绘制星形的内半径与其对应的圆,使用户更直观的观察到星形所在位置,其中动态绘制的图形只是临时绘制不会保存在画布中,参考代码如下:

    const getRadius1 = new MxCADUiPrPoint()
    getRadius1.setMessage('\n指定星形的内半径:')
    getRadius1.setUserDraw((pt, pw) => {
    // 通过计算两点之间的距离得到星形内半径  
    let radius = pt.distanceTo(center)
     pw.drawMcDbEntity(new McDbCircle(center.x, center.y, center.z, radius))
    pw.drawMcDbEntity(new McDbLine(center, pt))
    })
    const pt1 = await getRadius1.go()
    if (!pt1) return;

    其动态显示效果如下:

    若想了解更详细的动态绘制内容,请参考 mxcad | 动态绘制

  3. 获取星形的外半径,根据上述操作中获取的星形顶点数,在内外半径所在圆上交错取点,获取到目标星形的所有端点,然后通过实例化一个 McDbPolyline() 多义线绘制星形,在该过程中用户能够动态调整星形的大小,确定星形大小后,调用 mxcad 的drawEntity()方法在图纸上绘制最终的目标星形,参考代码如下:

    // 获取内半径
    const radius1 = pt1.distanceTo(center)
    const circle1 = new McDbCircle(center.x, center.y, center.z, radius1)
    // 定义存放星形端点的数组
    let pointsArr: McGePoint3d[] = []
    const getRadius2 = new MxCADUiPrPoint()
    getRadius2.setMessage('\n指定星形的外半径:')
    // 动态绘制星形
    getRadius2.setUserDraw((pt, pw) => {
     let circle2 = new McDbCircle(center.x, center.y, center.z, pt.distanceTo(center));
     // 获取两个半径所在圆的曲线长
     let length1 = circle1.getLength();
     let length2 = circle2.getLength();
     if (!length1 || !length2) return;
     let pointArr: McGePoint3d[] = [];
     // 根据星形顶点数在两个圆上交错取点,得到星形的所有端点
     for (let i = 0; i < starNum * 2; i++) {
         let point1 = circle1.getPointAtDist(length1.val / (starNum * 2) * i);
         if (!point1.ret) return
         let point2 = circle2.getPointAtDist(length2.val / (starNum * 2) * i);
         if (!point2.ret) return
         if (i % 2 === 0) {
           pointArr.push(point1.val)
         } else {
         pointArr.push(point2.val)
         }
     }
     // 实例化多义线,连接星形所有端点绘制闭合曲线
     let pl = new McDbPolyline();
     pointArr.forEach(pt => {
       pl.addVertexAt(pt)
     })
     pl.isClosed = true
     pw.drawMcDbEntity(pl)
     // 存储星形端点
     pointsArr = [...pointArr]
    })
    const pt2 = await getRadius2.go()
    if (!pt2) return;
    let mxcad = MxCpp.App.getCurrentMxCAD();
    let pl = new McDbPolyline();
    pointsArr.forEach(pt => {
     pl.addVertexAt(pt)
    })
    pl.isClosed = true;
    mxcad.drawEntity(pl)

    其绘制效果如下:

5. 最终绘制的目标星形效果如下:

除了上述绘制星形的方法外,还可以根据 mxcad 官方文档结合 mxcad API自行实现其他绘制星形的方法。

DEMO源码:

https://gitee.com/mxcadx/mxdraw-article/blob/master/使用mxcad绘制星形/demo.zip

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 2

这东西能一直免费吗?

2周前 评论
MxCAD (楼主) 1周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!