找回密码
 立即注册

QQ登录

只需一步,快速开始

微信扫码登录

搜索
查看: 580|回复: 1

[图文教程] 在线CAD实现圆转多边形功能

[复制链接]

299

主题

20

回帖

3984

积分

中尉

积分
3984

活跃会员

发表于 2024-4-7 16:16:36 | 显示全部楼层 |阅读模式
前言

在线CAD SDK的集成过程中,甲方客户可能有实现圆转多边形功能的需求,作为开发者如何利用WEB CAD SDK展现此功能效果呢?本章节我们重点讲述一下。

环境搭建

1. 搭建绘图环境,创建一个mxcad项目

2. 在项目中添加命令行,实现功能的动态交互功能。

基于mxcad库实现圆转多边形功能

圆转多边形功能是根据用户输入的边数将目标圆转变成正多边形,其中转变方式分两种情况,一种是转换后的正多边形内接于目标圆,一种是转换后的正多边形外切于圆。下面我们将分别介绍如何实现这两种转换方式。

1. 内接于圆:即目标圆为多边形的外接圆,它与多边形的每个顶点都相接。因此我们可以通过在目标圆上均匀取点找到多边形的所有顶点,最后通过多段线闭合连接成多边形,如下图:
image-20240402105127132.png

2. 外切于圆:即目标圆为多边形的内切圆,它与多边形的每条边都相切,且与多边形的中心在同一直线上。因此我们可以通过获取多边形的外切圆反向绘制多边形。根据多边形条数求得多边形的每个内角度数,再根据目标圆的半径值可求的多边形外切圆半径值:目标圆半径 / sin(90 - (360 / (num * 2))),如下图所示:
image-20240402110513671.png

使用 mxcad 库实现完整圆转多边形功能

1. 首先选中目标对象,选择时筛选出圆对象,参考代码如下:
  1. <font size="3">   ```ts
  2.    // 选中圆
  3.    let filter = new MxCADResbuf();
  4.    filter.AddMcDbEntityTypes("CIRCLE");
  5.    let aryId = await MxCADUtility.userSelect("选择要转成多边形的对象", filter);
  6.    if (aryId.length == 0) {
  7.        return;
  8.    }
  9.    ```</font>
复制代码

2. 通过命令行交互让用户设置多边形边数,默认为正五边形。

  1. <font size="3">   ```ts
  2.    let getNum = new MxCADUiPrInt();
  3.    getNum.setMessage('设置多边形边数');
  4.    let num = await getNum.go() || 5;
  5.    getNum.clearLastInputPoint()
  6.    if (!num) return;
  7.    ```</font>
复制代码

3. 然后让用户根据需求选择内接于圆或外切于圆的圆转多边形转换方式,默认选择内接于圆方式。

  1. <font size="3">   ```ts
  2.    const getPoint = new MxCADUiPrPoint();
  3.    getPoint.setMessage("\n输入选项")
  4.    getPoint.setKeyWords("[内接于圆(I)/外切于圆(C)]")
  5.    getPoint.clearLastInputPoint()
  6.    await getPoint.go();
  7.    let tollType = 'inside'
  8.    if (getPoint.isKeyWordPicked("i")) tollType = 'inside'
  9.    if (getPoint.isKeyWordPicked("c")) tollType = 'outside'
  10.    ```</font>
复制代码

4. 最后根据用户输入关键字确定转换方式,绘制多边形。

  1. <font size="3">```ts
  2.     let mxcad = MxCpp.getCurrentMxCAD();
  3.     aryId.forEach(async (id) => {
  4.         let event: any = await id.getMcDbEntity();
  5.         let cricle = event as McDbCircle;
  6.         let arr1: McGePoint3d[] = [];
  7.         if (tollType === 'inside') {
  8.             //    多边形内切圆
  9.             for (let i = 0; i < num; i++) {
  10.                 let point = cricle.getPointAtDist(cricle.getLength().val / num * i);
  11.                 if (point.ret) arr1.push(point.val)
  12.             }
  13.             let pl1 = new McDbPolyline();
  14.             arr1.forEach(i => {
  15.                 pl1.addVertexAt(i)
  16.             })
  17.             pl1.isClosed = true;
  18.             mxcad.drawEntity(pl1);
  19.         } else if (tollType === 'outside') {
  20.             //  多边形外切圆
  21.             /**
  22.              * 知道三个角加一条边求其他两边
  23.              * 一条边:r
  24.              * 三个角 90 360/num*2
  25.              */
  26.             let angle = 90 - (360 / (num * 2))
  27.             let sinValue = Math.sin(angle * Math.PI / 180); // 返回0.5
  28.             let R = cricle.radius / sinValue;
  29.             let r = new McDbCircle();
  30.             r.center = cricle.center;
  31.             r.radius = R;
  32.             let arr2: McGePoint3d[] = [];
  33.             for (let i = 0; i < num; i++) {
  34.                 let point = r.getPointAtDist(r.getLength().val / num * i);
  35.                 if (point.ret) arr2.push(point.val)
  36.             }
  37.             let pl2 = new McDbPolyline();
  38.             arr2.forEach(i => {
  39.                 pl2.addVertexAt(i)
  40.             })
  41.             pl2.isClosed = true;
  42.             mxcad.drawEntity(pl2);
  43.         }
  44.         event.erase()
  45.     })
  46. ```</font>
复制代码

实现效果如下:

image-20240402112211243.png

DEMO源码下载地址

https://gitee.com/mxcadx/mxdraw-article/blob/master/使用mxcad实现圆转多边功能/demo.7z







2

主题

503

回帖

1万

积分

中校

积分
11178
发表于 2024-4-7 16:28:35 | 显示全部楼层
发现一个bag,多边形只能“内接于圆”,而不能“内切于圆”。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

咨询QQ:1359218528|发帖须知!|Archiver|手机版|小黑屋|UG爱好者论坛 ( 京ICP备10217105号-2 )

GMT+8, 2024-12-25 13:55

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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