明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 749|回复: 0

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

[复制链接]
发表于 2024-3-29 11:29:46 | 显示全部楼层 |阅读模式
本帖最后由 MxDraw 于 2024-3-29 11:32 编辑

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

基础准备
1. 搭建绘图环境,创建一个mxcad项目具体操作请参考mxcad | 快速入门
2. 在项目中添加命令行,实现功能的动态交互功能具体操作请参考mxcad | 命令行

绘制星形
1. 首先通过 mxcad 提供的获取用户输入整数的[MxCADUiPrInt()]类来获取星形顶点数。
  1. const starVert = new MxCADUiPrInt()
  2. starVert.setMessage("\n请输入星形顶点数:")
  3. const starNum = await starVert.go()
  4. if (!starNum) return;
复制代码
其命令行交互如下:

2. 通过 mxcad 提供的获取用户UI交互取点的[MxCADUiPrPoint()]类来获取星形圆心所在点的位置。
  1. const getCenter = new MxCADUiPrPoint()
  2. getCenter.setMessage("\n指定星形中心点:")
  3. const center = await getCenter.go()
  4. if (!center) return;
复制代码

3. 利用 mxcad 的动态绘制功能绘制星形的内半径与其对应的圆,使用户更直观的观察到星形所在位置其中动态绘制的图形只是临时绘制不会保存在画布中,参考代码如下:
  1. const getRadius1 = new MxCADUiPrPoint()
  2. getRadius1.setMessage('\n指定星形的内半径:')
  3. getRadius1.setUserDraw((pt, pw) => {
  4.   // 通过计算两点之间的距离得到星形内半径  
  5.     let radius = pt.distanceTo(center)
  6.     pw.drawMcDbEntity(new McDbCircle(center.x, center.y, center.z, radius))
  7.     pw.drawMcDbEntity(new McDbLine(center, pt))
  8. })
  9. const pt1 = await getRadius1.go()
  10. if (!pt1) return;
复制代码
其动态显示效果如下:
若想了解更详细的动态绘制内容,请参考[mxcad | 动态绘制

4. 获取星形的外半径,根据上述操作中获取的星形顶点数在内外半径所在圆上交错取点,获取到目标星形的所有端点然后通过实例化一个 [McDbPolyline()]多义线绘制星形,在该过程中用户能够动态调整星形的大小确定星形大小后,调用mxcad[drawEntity()]方法在图纸上绘制最终的目标星形,参考代码如下:
  1. // 获取内半径
  2. const radius1 = pt1.distanceTo(center)
  3. const circle1 = new McDbCircle(center.x, center.y, center.z, radius1)
  4. // 定义存放星形端点的数组
  5. let pointsArr: McGePoint3d[] = []
  6. const getRadius2 = new MxCADUiPrPoint()
  7. getRadius2.setMessage('\n指定星形的外半径:')
  8. // 动态绘制星形
  9. getRadius2.setUserDraw((pt, pw) => {
  10.     let circle2 = new McDbCircle(center.x, center.y, center.z, pt.distanceTo(center));
  11.     // 获取两个半径所在圆的曲线长
  12.     let length1 = circle1.getLength();
  13.     let length2 = circle2.getLength();
  14.     if (!length1 || !length2) return;
  15.     let pointArr: McGePoint3d[] = [];
  16.     // 根据星形顶点数在两个圆上交错取点,得到星形的所有端点
  17.     for (let i = 0; i < starNum * 2; i++) {
  18.         let point1 = circle1.getPointAtDist(length1.val / (starNum * 2) * i);
  19.         if (!point1.ret) return
  20.         let point2 = circle2.getPointAtDist(length2.val / (starNum * 2) * i);
  21.         if (!point2.ret) return
  22.         if (i % 2 === 0) {
  23.           pointArr.push(point1.val)
  24.         } else {
  25.         pointArr.push(point2.val)
  26.         }
  27.     }
  28.     // 实例化多义线,连接星形所有端点绘制闭合曲线
  29.     let pl = new McDbPolyline();
  30.     pointArr.forEach(pt => {
  31.       pl.addVertexAt(pt)
  32.     })
  33.     pl.isClosed = true
  34.     pw.drawMcDbEntity(pl)
  35.     // 存储星形端点
  36.     pointsArr = [...pointArr]
  37. })
  38. const pt2 = await getRadius2.go()
  39. if (!pt2) return;
  40. let mxcad = MxCpp.App.getCurrentMxCAD();
  41. let pl = new McDbPolyline();
  42. pointsArr.forEach(pt => {
  43.     pl.addVertexAt(pt)
  44. })
  45. pl.isClosed = true;
  46. mxcad.drawEntity(pl)
复制代码
其绘制效果如下:

5. 最终绘制的目标星形效果如下:
除了上述绘制星形的方法外,还可以根据[mxcad 官方文档()结合[mxcad API]自行实现其他绘制星形的方法。

DEMO
源码:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 04:29 , Processed in 0.180071 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表