网页CAD(JS Vue 预览dwg)如何二次开发常用的CAD编辑功能

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
可观测可视化 Grafana 版,10个用户账号 1个月
简介: ```markdown# CAD网页编程概览- 使用mxcad库,实现CAD操作如删除、复制、镜像、移动和旋转。- `erase()`方法删除实体,`clone()`配合`transformBy()`用于复制和编辑。- `mirror()`和`transformBy(setMirror)`执行镜像操作,基于参考线。- `move()`和`transformBy(setToTranslation)`实现移动功能。- `rotate()`和`transformBy(setToRotation)`进行旋转,支持角度输入。```

前言

网页CAD中常见的修改和编辑命令有很多,例如移动、复制、缩放、旋转、镜像、剪切、延伸、阵列、修改和编辑,这些命令可以帮助用户对绘图进行修改、调整和优化,提高工作效率和设计质量。mxcad 根据该需求提供了相应接口和方法,实现了CAD中常见的修改和编辑命令。这些操作中涉及到对点、向量、矩阵、角度等的计算,具体规则可参考[指南-数学库],也可前往在线DEMO查看具体效果。

删除

我们可以通过调用实体的[erase()]方法删除作图过程中的图线和多余的图线,参考代码如下:

import { MxCADUtility, McObjectId } from "mxcad"
const objIds = MxCADUtility.getCurrentSelect()
objIds.forEach((objId: McObjectId) => {
    objId.erase()
})

效果示例如下:
image-7274.png
image-20240621095201843.png

复制

我们可以通过调用实体的 clone() 方法复制多个对象,也可对一个或多个对象进行多次复制。在复制完成后可点击复制实体移动到目标位置,参考代码如下:

import { MxCADUtility, McDbEntity, McObjectId, MxCpp } from "mxcad"
const objIds = MxCADUtility.getCurrentSelect()
objIds.forEach((objId: McObjectId) => {
    const event = objId.getMcDbEntity()
    if (!event) return;
    const event_clone = event.clone() as McDbEntity
    MxCpp.getCurrentMxCAD().drawEntity(event_clone)
})

此外,我们还可以调用实体的[transformBy()]方法复制对象,该方法是通过变换矩阵实现图形的编辑,具体矩阵变换原理可参考[指南数学库中的矩阵-mcgematrix3d],点击[McGeMatrix3d-clone()]查看矩形变换详细方法和属性,参考代码如下:

import { MxCADUtility, McDbEntity, McObjectId,  MxCpp} from "mxcad"
const objIds = MxCADUtility.getCurrentSelect()
objIds.forEach((objId: McObjectId) => {
    const event = objId.getMcDbEntity()
    if (!event) return;
    const event_clone = event.clone() as McDbEntity
    const matrix = new McGeMatrix3d()
    matrix.clone()
    event_clone.transformBy(matrix)
    MxCpp.getCurrentMxCAD().drawEntity(event_clone)
})

效果示例如下:
image-20240621095922868.png
image-20240621100043704.png

镜像

我们可以通过调用实体的 mirror() 方法将指定的对象按指定的参考线作镜像处理,代码如下:

import { MxCADUtility, McObjectId,McGeMatrix3d, MxCADUiPrPoint } from "mxcad"
async function Mx_test_mirror(){
    const objIds = MxCADUtility.getCurrentSelect()
    const getPt1 = new MxCADUiPrPoint()
    getPt1.setMessage("指定镜像参考线的开始点")
    const pt1 = await getPt1.go()
    if(!pt1) return
    const getPt2 = new MxCADUiPrPoint()
    getPt2.setMessage("指定镜像参考线的结束点")
    const pt2 = await getPt2.go()
    if(!pt2) return
    objIds.forEach((objId: McObjectId) => {
        const event = objId.getMcDbEntity()
        if(!event) return
        event.mirror(pt1, pt2)
    })
}

此外,我们还可以调用实体的transformBy()方法镜像处理对象。该方法是通过变换矩阵实现图形的编辑,具体矩阵变换原理可参考[指南数学库中的矩阵-mcgematrix3d],点击[McGeMatrix3d-setMirror()]查看矩形变换详细方法和属性,参考代码如下:

import { MxCADUtility, McObjectId,McGeMatrix3d, MxCADUiPrPoint } from "mxcad"
async function Mx_test_mirror(){
    const objIds = MxCADUtility.getCurrentSelect()
    const getPt1 = new MxCADUiPrPoint()
    getPt1.setMessage("指定镜像参考线的开始点")
    const pt1 = await getPt1.go()
    if(!pt1) return
    const getPt2 = new MxCADUiPrPoint()
    getPt2.setMessage("指定镜像参考线的结束点")
    const pt2 = await getPt2.go()
    if(!pt2) return
    objIds.forEach((objId: McObjectId) => {
        const event = objId.getMcDbEntity()
        if(!event) return
        const matrix = new McGeMatrix3d()
        matrix.setMirror(pt1,pt2)
        event.transformBy(matrix)
    })
}

效果示例如下:
image-20240621100901368.png
image-20240621101159826.png

移动

我们可以通过调用实体的[move()]方法移动目标对象,该移动方法只是变更对象的原始位置,并不复制对象,参考代码如下:

import { MxCADUtility, McGePoint3d, McObjectId } from "mxcad"
const objIds = MxCADUtility.getCurrentSelect()
const pt1= new McGePoint3d(0,0,0)
const pt2 = new McGePoint3d(100,100,0)
objIds.forEach((objId: McObjectId) => {
    objId.getMcDbEntity()?.move(pt1, pt2)
})

此外,我们还可以调用实体的transformBy()方法移动对象。该方法是通过变换矩阵实现图形的编辑,具体矩阵变换原理可参考[指南数学库中的矩阵-mcgematrix3d],点击[McGeMatrix3d-setToTranslation()]查看矩形变换详细方法和属性,参考代码如下:

import { MxCADUtility, McGePoint3d, McObjectId } from "mxcad"
const objIds = MxCADUtility.getCurrentSelect()
const pt1= new McGePoint3d(0,0,0)
const pt2 = new McGePoint3d(100,100,0)
objIds.forEach((objId: McObjectId) => {
    const event = objId.getMcDbEntity()
    if(!event) return
    const matrix = new McGeMatrix3d()
    const v = pt2.sub(pt1)
    matrix.setToTranslation(v)
    event.transformBy(matrix)
})

效果示例如下:
image-20240621103019962.png
image-20240621103056583.png

旋转

我们可以通过调用实体的[rotate()]方法将所选对象绕指定基点旋转指定角度,参考代码如下:

import { MxCADUtility, MxCADUiPrPoint } from "mxcad"
async function Mx_test_rotate(){
    const objIds = MxCADUtility.getCurrentSelect()
    const getPt1 = new MxCADUiPrPoint()
    getPt1.setMessage("指定旋转基点")
    const pt1 = await getPt1.go()
    if(!pt1) return
    const getPt2 = new MxCADUiPrPoint()
    getPt2.setMessage("指定旋转角度")
    getPt2.setUserDraw((pt,pw)=>{
        const line = new McDbLine(pt1.x,pt1.y,pt1.z,pt.x,pt.y,pt.z)
        pw.drawMcDbEntity(line)
        objIds.forEach((objId: McObjectId) => {
            const event = objId.getMcDbEntity()?.clone() as McDbEntity
            if(!event) return
            // 旋转角度
            const dRotationAngle = pt1.sub(pt).angleTo2(McGeVector3d.kXAxis, McGeVector3d.kZAxis);
            event.rotate(pt1, dRotationAngle)
            pw.drawMcDbEntity(event)
        })
    })
    const pt2 = await getPt2.go()
    if(!pt2) return
    objIds.forEach((objId: McObjectId) => {
        const event = objId.getMcDbEntity()
        if(!event) return
        const dRotationAngle = pt1.sub(pt2).angleTo2(McGeVector3d.kXAxis, McGeVector3d.kZAxis);
        event.rotate(pt1, dRotationAngle)
    })
}

此外,我们还可以调用实体的 transformBy() 方法旋转对象,该方法是通过变换矩阵实现图形的旋转,具体矩阵变换原理可参考指南数学库中的矩阵-mcgematrix3d,点击[McGeMatrix3d-setToTranslation()]查看矩形变换详细方法和属性,参考代码如下:

import { MxCADUtility, MxCADUiPrPoint, McGeMatrix3d, McObjectId } from "mxcad"
async function Mx_test_rotate(){
    const objIds = MxCADUtility.getCurrentSelect()
    const getPt1 = new MxCADUiPrPoint()
    getPt1.setMessage("指定旋转中心点")
    const pt1 = await getPt1.go()
    if(!pt1) return
    objIds.forEach((objId: McObjectId) => {
        const event = objId.getMcDbEntity()
        if(!event) return
        // 以pt1为中心点 绕z轴 旋转45度
        const matrix = new McGeMatrix3d()
        matrix.setToRotation(Math.PI / 4, McGeVector3d.kZAxis, pt1)
        event.transformBy(matrix)
    })
}

效果示例如下:
image-20240621104258903.png
image-20240621104348458.png

偏移

我们可以通过调用实体的[offsetCurves()]方法将直线、圆、多线段等作同心复制,相当于平行移动一段距离后进行复制,参考代码如下:

import { MxCADResbuf, MxCADUtility, MxCpp } from "mxcad"
async function Mx_test_offset(){
    const filter = new MxCADResbuf();
    filter.AddMcDbEntityTypes("LINE") ;
    const objIds = MxCADUtility.getCurrentSelect(filter)
    const getPt1 = new MxCADUiPrPoint()
    getPt1.setMessage("指定偏移点")
    const pt1 = await getPt1.go()
    if(!pt1) return
    objIds.forEach((objId: McObjectId) => {
        const event = objId.getMcDbEntity() ;
       let objArr = (event as McDbLine).offsetCurves(100,pt1)
       if (objArr.length() === 0) return;
       objArr.forEach(obj=>{
        MxCpp.getCurrentMxCAD().drawEntity(obj as McDbEntity)
       })
    })
}

效果示例如下:
image-20240621104733460.png
image-20240621104849568.png

缩放

我们可以通过调用实体的[scaleEntity]方法对图形进行自由缩放,参考代码如下:

import { MxCADUtility, MxCADUiPrPoint } from "mxcad"
async function Mx_test_scale(){
    const objIds = MxCADUtility.getCurrentSelect()
    const getPt = new MxCADUiPrPoint()
    getPt.setMessage("指定缩放基点")
    const pt = await getPt.go()
    if(!pt) return
    objIds.forEach((objId: McObjectId) => {
        const event = objId.getMcDbEntity()
        if(!event) return
         event.scaleEntity(pt,0.2)
    })
}

此外,我们还可以调用实体的 transformBy() 方法缩放对象。该方法是通过变换矩阵实现图形的缩放,具体矩阵变换原理可参考[指南数学库中的矩阵-mcgematrix3d],点击[McGeMatrix3d-setToScaling()]查看矩形变换详细方法和属性,参考代码如下:

import { MxCADUtility, MxCADUiPrPoint } from "mxcad"
async function Mx_test_scale(){
    const objIds = MxCADUtility.getCurrentSelect()
    const getPt = new MxCADUiPrPoint()
    getPt.setMessage("指定缩放中心点")
    const pt = await getPt.go()
    if(!pt) return
    objIds.forEach((objId: McObjectId) => {
        const event = objId.getMcDbEntity()
        if(!event) return
        const matrix = new McGeMatrix3d()
        matrix.setToScaling(0.2, pt)
        event.transformBy(matrix)
    })
}

效果示例如下:
image-20240621105517340.png
image-20240621105600990.png

相关文章
|
3月前
|
JavaScript 算法 开发者
如何用JS实现在网页上通过鼠标移动批量选择元素的效果?
本文介绍了类似电脑桌面通过鼠标选择多个图标的实现原理。主要通过监听mousedown、mousemove和mouseup事件,动态调整选择框大小并计算与元素的重叠情况。提供了角重叠和相交重叠的检测方法,并附有示例代码和在线演示链接,方便开发者参考与测试。
149 56
|
2月前
|
Web App开发 数据采集 JavaScript
动态网页爬取:Python如何获取JS加载的数据?
动态网页爬取:Python如何获取JS加载的数据?
442 58
|
4月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
203 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
27天前
|
前端开发
个人征信PDF无痕修改软件,个人征信模板可编辑,个人征信报告p图神器【js+html+css仅供学习用途】
这是一款信用知识学习系统,旨在帮助用户了解征信基本概念、信用评分计算原理及信用行为影响。系统通过模拟数据生成信用报告,涵盖还款记录
|
2月前
|
数据采集 Web App开发 JavaScript
Python爬虫如何获取JavaScript动态渲染后的网页内容?
Python爬虫如何获取JavaScript动态渲染后的网页内容?
|
4月前
|
前端开发 JavaScript
【Javascript系列】Terser除了压缩代码之外,还有优化代码的功能
Terser 是一款广泛应用于前端开发的 JavaScript 解析器和压缩工具,常被视为 Uglify-es 的替代品。它不仅能高效压缩代码体积,还能优化代码逻辑,提升可靠性。例如,在调试中发现,Terser 压缩后的代码对删除功能确认框逻辑进行了优化。常用参数包括 `compress`(启用压缩)、`mangle`(变量名混淆)和 `output`(输出配置)。更多高级用法可参考官方文档。
218 11
|
5月前
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
157 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
5月前
|
SQL JavaScript 安全
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
207 11
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
|
6月前
|
JavaScript 前端开发 安全
盘点原生JS中目前最没用的几个功能API
在JavaScript的发展历程中,许多功能与API曾风光无限,但随着技术进步和语言演化,部分功能逐渐被淘汰或被更高效的替代方案取代。例如,`with`语句使代码作用域复杂、可读性差;`void`操作符功能冗余且影响可读性;`eval`函数存在严重安全风险和性能问题;`unescape`和`escape`函数已被`decodeURIComponent`和`encodeURIComponent`取代;`arguments`对象则被ES6的剩余参数语法替代。这些变化体现了JavaScript不断优化的趋势,开发者应紧跟技术步伐,学习新技能,适应新技术环境。
85 10
|
6月前
|
JavaScript 前端开发
【Vue.js】监听器功能(EventListener)的实际应用【合集】
而此次问题的核心就在于,Vue实例化的时机过早,在其所依赖的DOM结构尚未完整构建完成时就已启动挂载流程,从而导致无法找到对应的DOM元素,最终致使计算器功能出现异常,输出框错误地显示“{{current}}”,并且按钮的交互功能也完全丧失响应。为了让代码结构更为清晰,便于后续的维护与管理工作,我打算把HTML文件中标签内的JavaScript代码迁移到外部的JS文件里,随后在HTML文件中对其进行引用。
89 8