|
本帖最后由 CAD画图 于 2023-12-11 15:59 编辑
前言
在mxcad中绘制矩形,本质上还是绘制多段线,那如何用mxcad中的多段线去绘制一个支持倒角和圆角的矩形呢,在autocad中绘制一个矩形会通过一些命令或者输入关键字来确定是否需要倒角圆角或者通过面积, 宽高去绘制。下面我们将模仿autocad的绘制矩形的交互绘制, 完整的实现一个动态交互式的绘制一个矩形出来。
在线CAD功能测试:https://demo.mxdraw3d.com:3000/mxcad/,效果如下:
命令交互初始化工作
对于命令交互, 我们用尽量简洁的方式实现, 代码如下:
- import { MxFun } from "mxdraw"
- const input = document.createElement("input")
- const tip = document.createElement("div")
- const dis = document.createElement("div")
- document.body.appendChild(tip)
- document.body.appendChild(input)
- document.body.appendChild(dis)
- // 命令交互
- input.addEventListener("keydown", (e: KeyboardEvent) => {
- // 讲输入框的值和按键信息传递给mxdraw中进行处理
- MxFun.setCommandLineInputData((e.target as HTMLInputElement).value, e.keyCode);
- // 回车清空输入
- if(e.keyCode === 13) (e.target as HTMLInputElement).value = ""
- })
- // 接收提示信息和命令信息
- MxFun.listenForCommandLineInput(({ msCmdTip, msCmdDisplay, msCmdText }) => {
- tip.innerText = msCmdTip + msCmdText
- dis.innerText = msCmdDisplay
- }
- );
复制代码 绘制矩形
首先矩形一般由两个对角点来绘制出完整的矩形, 所以,我们第一步自然是获取对角点。
通过mxcad提供的获取用户输入的一些类:MxCADUiPrPoint获取点、MxCADUiPrDist获取距离、MxCADUiPrInt获取数字、MxCADUiPrKeyWord获取关键词来交互式的绘制矩形
我们可以用MxCADUiPrPoint获取到用户点击的对角点, 以及其他的几个类获取到用户的不同输入, 比如距离、数字、关键词等等。
根据这些用户输入, 我们来一个动态可交互的确认一个矩形如何绘制
绘制矩形主要分为以下几个步骤:
1.先获取第一个对角点
2.然后看看用户是否输入了关键词, 根据关键词获取对应的参数, 比如获取倒角距离,圆角半径等等 然后重新回到第一步重新获取角点
3.在有了第一个角度后,进行动态绘制矩形
4.获取第二个对角点, 生成矩形并绘制
其中一些关键词可能导致不同的绘制方式, 每个关键词对应不同处理。
首先获取对角点的代码比较简单,代码如下:
- import { MxCADUiPrPoint } from "mxcad"
- const getPoint = new MxCADUiPrPoint();
- const pt1 = await getPoint.go()
- console.log("对角点", pt1)
复制代码 然后关键词就算有一些简单必要的格式: 首先如果不需要给用户任何提示 可以直接写关键词例如:A B用空格分隔每个关键词 如果需要对应的说明提示则需要加[]然后里面的内容格式则是提示(关键词),最后用/分割每个关键词 例如:[倒角(C)/圆角(F)/宽度(W)]
- getPoint.setKeyWords("[倒角(C)/圆角(F)/宽度(W)]")
- // 这里是点击, 但是它也可能没有点击,而是输入了关键词,这时返回的是null
- await getPoint.go()
- // 这里可以直接判断是否输入了某个关键词
- if(getPoint.isKeyWordPicked("C"))
复制代码 然后我们对角点,倒角距离,圆半径这些参数来确定矩形的坐标点了。 首先最普通的矩形坐标点,我们通过两个对角点生成:
- import { McGePoint3d } from "mxcad"
- const getRectPoints = (pt1: McGePoint3d, pt3: McGePoint3d): McGePoint3d[] => {
- const pt2 = new McGePoint3d(pt1.x, pt3.y, pt1.z);
- const pt4 = new McGePoint3d(pt3.x, pt1.y, pt3.z);
- return [pt1, pt2, pt3, pt4];
- };
复制代码 有了四个点,这个时候我们要考虑如果要对矩形进行倒角,我们就需要8个坐标点构成 也就是根据xy轴倒角的距离去做偏移,把一个坐标生成两个偏移后坐标, 代码如下:
- // 计算第二个对角点相对于第一个对角点的象限位置, 分别返回四象限
- const getQuadrant = (pt1: McGePoint3d, pt3: McGePoint3d) => {
- return [(pt3.x >= pt1.x && pt3.y >= pt1.y), (pt3.x < pt1.x && pt3.y >= pt1.y), (pt3.x < pt1.x && pt3.y < pt1.y), (pt3.x >= pt1.x && pt3.y < pt1.y)] as [boolean, boolean, boolean, boolean]
- }
- // 根据矩形的坐标点和两个倒角距离生成8个坐标点的多边形
- function calculateRoundedRectangleVertices(points: McGePoint3d[], chamferDistance1: number, chamferDistance2: number) {
- // 首先如果倒角距离为0, 则直接返回矩形坐标点
- if (chamferDistance1 === 0 && chamferDistance2 === 0) return points
- const [pt1, pt2, pt3, pt4] = points
- // 然后计算矩形宽高, 与倒角距离进行比较,如果不能对矩形倒角就返回矩形坐标点
- const width = pt1.distanceTo(pt4)
- const height = pt1.distanceTo(pt2)
- if ((width - Math.abs(chamferDistanceX) * 2) <= 0) return points
- if ((height - Math.abs(chamferDistanceY) * 2) <= 0) return points
- // 为了确保矩形偏移生成的倒角点是正确的, 需要根据不都的象限做一些偏移取反处理
- const [_, isPt3InQuadrant2, isPt3InQuadrant3, isPt3InQuadrant4] = getQuadrant(pt1, pt3)
- const chamferDistanceX = isPt3InQuadrant2 || isPt3InQuadrant3 ? -chamferDistance1 : chamferDistance1;
- const chamferDistanceY = isPt3InQuadrant3 || isPt3InQuadrant4 ? -chamferDistance2 : chamferDistance2;
- // 计算出正确的xy倒角偏移距离,就开始对矩形的四个点在x或者y上进行偏移
- const chamferedPt1 = new McGePoint3d(pt1.x + chamferDistanceX, pt1.y, pt1.z);
- const chamferedPt2 = new McGePoint3d(pt1.x, pt1.y + chamferDistanceY, pt1.z);
- const chamferedPt3 = new McGePoint3d(pt2.x, pt2.y - chamferDistanceY, pt2.z);
- const chamferedPt4 = new McGePoint3d(pt2.x + chamferDistanceX, pt2.y, pt2.z);
- const chamferedPt5 = new McGePoint3d(pt3.x - chamferDistanceX, pt3.y, pt3.z);
- const chamferedPt6 = new McGePoint3d(pt3.x, pt2.y - chamferDistanceY, pt3.z);
- const chamferedPt7 = new McGePoint3d(pt4.x, pt4.y + chamferDistanceY, pt4.z);
- const chamferedPt8 = new McGePoint3d(pt4.x - chamferDistanceX, pt4.y, pt4.z);
- const chamferedPolygon = [
- chamferedPt1,
- chamferedPt2,
- chamferedPt3,
- chamferedPt4,
- chamferedPt5,
- chamferedPt6,
- chamferedPt7,
- chamferedPt8,
- ];
- return chamferedPolygon;
- }
复制代码 然后我们就要考虑圆角了, 在上面我们已知矩形倒角后的坐标集合, 那么我们把相当于要把矩形倒角点的四个角从原来的直线变成圆弧。 在cad中多段线去绘制圆弧我们只需要计算它的凸度就可以形成圆弧了,现在已经知道矩形的倒角连成的直线,那么也就知道了圆弧的开始点和结束点。 我们根据mxcad中提供的一些运算方法计算出对应的凸度:篇幅限制,更多的内容请查询梦想CAD控件
通过上述关键代码的讲解, 结合如下完整绘制矩形的交互式代码阅读可以更好的理解mxcad中绘制矩形的具体实现方式 下面结合上述步骤描述实现了一个包含倒角/圆角/面积/尺寸四种不同的绘制方式,形成了根据用户的输入以不同方式绘制矩形的功能, 代码如下:
篇幅限制,更多的内容请查询梦想CAD控件
源码下载地址:
https://gitee.com/mxcadx/mxdraw-article/tree/master/使用mxcad绘制矩形/demo.zip
|
|