本帖最后由 MxDraw 于 2024-3-29 11:32 编辑
前言 在 mxcad 中绘制星形,本质上还是绘制多段线,下面我们将介绍如何使用mxcad中的多段线去绘制一个支持自定义大小与定点数的星形,实现一个动态交互式的绘制星形功能,在线CAD功能DEMO:在线CAD梦想画图
基础准备
绘制星形- const starVert = new MxCADUiPrInt()
- starVert.setMessage("\n请输入星形顶点数:")
- const starNum = await starVert.go()
- if (!starNum) return;
复制代码其命令行交互如下:
- const getCenter = new MxCADUiPrPoint()
- getCenter.setMessage("\n指定星形中心点:")
- const center = await getCenter.go()
- if (!center) return;
复制代码
3. 利用 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;
复制代码其动态显示效果如下:
4. 获取星形的外半径,根据上述操作中获取的星形顶点数,在内外半径所在圆上交错取点,获取到目标星形的所有端点,然后通过实例化一个 [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. 最终绘制的目标星形效果如下:
DEMO源码:
|