明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 207|回复: 3

在线CAD(web cad sdk)实现圆转多边形功能

[复制链接]
发表于 2024-4-8 09:56 | 显示全部楼层 |阅读模式
本帖最后由 MxDraw 于 2024-4-8 10:00 编辑

前言

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

环境搭建

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

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

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

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

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

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

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

2. 通过命令行交互让用户设置多边形边数,默认为正五边形。
  1. <font size="3">   let getNum = new MxCADUiPrInt();
  2.    getNum.setMessage('设置多边形边数');
  3.    let num = await getNum.go() || 5;
  4.    getNum.clearLastInputPoint()
  5.    if (!num) return;
  6. </font>
复制代码

3. 然后让用户根据需求选择内接于圆或外切于圆的圆转多边形转换方式,默认选择内接于圆方式。
  1. <font size="3">   const getPoint = new MxCADUiPrPoint();
  2.    getPoint.setMessage("\n输入选项")
  3.    getPoint.setKeyWords("\[内接于圆(I)/外切于圆(C)]")
  4.    getPoint.clearLastInputPoint()
  5.    await getPoint.go();
  6.    let tollType = 'inside'
  7.    if (getPoint.isKeyWordPicked("i")) tollType = 'inside'
  8.    if (getPoint.isKeyWordPicked("c")) tollType = 'outside'</font>
复制代码

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

DEMO源码下载地址




本帖子中包含更多资源

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

x
发表于 2024-4-8 15:32 | 显示全部楼层
真牛逼,十年如一日
发表于 2024-4-9 13:47 | 显示全部楼层
谢谢分享谢谢分享谢谢分享
 楼主| 发表于 2024-4-25 18:07 | 显示全部楼层

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

本版积分规则

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

GMT+8, 2024-5-1 04:01 , Processed in 0.289177 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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