HarmonyOS鸿蒙Next中H5在线CAD实现一种绘制圆弧的方式

HarmonyOS鸿蒙Next中H5在线CAD实现一种绘制圆弧的方式 前言

在线CAD绘制圆弧本质上是在网页端编辑DWG图纸,而DWG格式是无法直接在网页端编辑的,因此要先安装梦想CAD控件的后台转换程序,将图纸转换成mxweb格式,然后传送给前台进行编辑,其中转换方法和原理请查看快速入门的《编辑模式原理说明》章节,如下图:


注意:如果你对mxdraw不是很了解建议看看官方文档: https://mxcadx.gitee.io/mxdraw_docs/start/abstract.html


网页CAD绘制圆弧的方式有很多种,而mxdraw库的方式是通过继承Mx3PointArc类来实现两点绘制圆弧的功能,类似于多段线画圆弧,只需要确定两个点就可以画一个圆弧的效果,这两个点分别是圆弧的开始点和圆弧的结束点,下面讲一下具体实现方法。

在线CAD测试:https://demo.mxdraw3d.com:3000/mxcad/

使用Mx3PointArc

在此之前先了解以下内容: https://mxcadx.gitee.io/mxdraw_api_docs/classes/Mx3PointArc.html

首先Mx3PointArc是通过给定的三个点来绘制圆弧的一个类。这三个点分别是起点(point1)、终点(point2)和第三个点(point3),其中第三个点是圆弧上的任意一点。

绘制圆弧的原理是通过计算得出圆的中心点(center)、半径(radius)以及起始角度(startAngle)和终止角度(endAngle)来确定圆弧的形状。

具体的步骤如下:

  1. 首先通过三个点计算出圆的中心点(center)。这可以通过计算两条垂直平分线的交点来实现。假设已知点A(point1)、点B(point2)和点C(point3),则可以计算出AB线段的中点和垂直于AB的斜率,再计算出BC线段的中点和垂直于BC的斜率,最后求出这两条垂直平分线的交点即为圆的中心点。
  2. 接下来,通过圆心和起点(point1)的距离来确定圆的半径(radius)。
  3. 然后,通过计算圆心到起点、圆心到终点和圆心到第三个点的角度,可以得到起始角度(startAngle)和终止角度(endAngle)。这可以通过三角函数来计算得出。
  4. 最后,根据圆弧的顺时针或逆时针方向进行调整。如果是顺时针方向,且起始角度小于终止角度,则将起始角度加上2π;如果是逆时针方向,且起始角度大于终止角度,则将终止角度加上2π。

通过以上步骤,使用给定的三个点来计算出圆弧中心点(center)、半径(radius)、起始角度(startAngle)和终止角度(endAngle),从而通过THREE.EllipseCurve计算得出最终构成圆弧的(向量集合)points,并通过mxdraw提供的自定义形状图形类MxDbShape渲染绘制出圆弧。

Mx3PointArc基础继承

要实现两点画圆弧,就要自动去计算point3的位置,我们先继承Mx3PointArc, 重写一些简单的代码:

import { Mx3PointArc } from "mxdraw"

class MxDbArc extends Mx3PointArc {

  get startPoint() {
    return this.point1
  }

  set startPoint(v) {
    this.point1 = v
  }

  get endPoint() {
    return this.point2
  }

  set endPoint(v) {
    this.point2 = v
  }

  getTypeName(): string {
    return "MxDbArc"
  }

  getGripPoints(): THREE.Vector3[] {
    return [this.point1, this.point2, this.point3]
  }
}

上面的代码我们继承了Mx3PointArc 并重写了图形类的名称和显示的控制夹点数量,并且新增了startPoint和endPoint 访问器,这样变量命名的意思更加明确。

计算point3(圆弧中点)

下面计算this.point3控制点,在绘制完成后,这个控制点是一个弧线中点的位置,所以我们在绘制时可以把this.point3当成弧线中点计算,以下是具体代码:

import { Mx3PointArc, McGiWorldDrawType, McGiWorldDraw } from "mxdraw"

class MxDbArc extends Mx3PointArc {

  // ...

  worldDraw(pWorldDraw: McGiWorldDraw): void {
    // 这里比较特殊,只有在动态拖动的绘制时去计算中点,才能达到我们想要的效果
    if (pWorldDraw.getType() === McGiWorldDrawType.kDynDragDraw) {
      // 计算中点 如果没有成功计算中点,我们也需要一个点来支撑下次的中点运算,
      // 所以`this.point3`如果发现没有成功计算中点是需要一个默认值的
      this.point3 = this.getArcMidPoint()
      if (!this.point3) this.point3 = new THREE.Vector3(this.point1.x, this.point2.y)
    }
    super.worldDraw(pWorldDraw)
  }

  // 默认圆弧是不需要闭合的
  closed = false

  /** 获取圆弧线中点坐标 */
  getArcMidPoint() {
    const THREE = MxFun.getMxFunTHREE()
    let { startAngle, endAngle, center, radius, clockwise, autoClockwise } = this
    if (center.x === 0 && center.y === 0) return

    // 这里主要是更新计算必要的一些构成圆弧的参数 圆心、半径、角度、顺逆时针
    this.upDateCenter(this.point1, this.point2, this.point3)
    this.upDateRadius(this.point1)
    const [angle1, angle2, angle3] = this.compute3PointAngle()
    this.startAngle = THREE.MathUtils.degToRad(angle1)
    this.endAngle = THREE.MathUtils.degToRad(angle2)
    this.upDataClockwise(angle1, angle2, angle3)

    // 根据顺逆时针方向进行调整
    if (clockwise) {
      if (startAngle < endAngle) {
        startAngle += 2 * Math.PI;
      }
    } else {
      if (startAngle > endAngle) {
        endAngle += 2 * Math.PI;
      }
    }

    const midAngle = (startAngle + endAngle) / 2;
    const midX = center.x + radius * Math.cos(midAngle);
    const midY = center.y + radius * Math.sin(midAngle);
    return new THREE.Vector3(midX, midY, 0)
  }
}

实现绘制函数

现在实现以下绘制函数,其他就算得到圆弧开始点和结束点:

import { MrxDbgUiPrPoint, MxFun } from "mxdraw"

const drawArc = async () => {
  const getPoint = new MrxDbgUiPrPoint()
  const arc = new MxDbArc()
  const p1 = await getPoint.go()
  if (!p1) return
  arc.startPoint = p1
  getPoint.setUserDraw((point, draw) => {
    arc.endPoint = point
    draw.drawCustomEntity(arc)
  })
  const p2 = await getPoint.go()
  if (!p2) return
  arc.endPoint = p2
  MxFun.getCurrentDraw().addMxEntity(arc)
}

最后在需要画圆弧的时候调用drawArc()就可以通过指定开始点和结束点来确定一个圆弧了,效果图如下:

第一次绘制过程中的截图:

绘制完成点击圆弧中点拖动的截图:

当然还有其他方式可以实现两点绘制圆弧, 目前这种方式是比较简单实用的一些使用mxdraw的技巧。

我们可以通过mxdraw提供的各种图形类去继承或者组合去实现更多好用且实用的图形和绘制能力。

关于组合与继承mxdraw中的图形类请参考: https://mxcadx.gitee.io/mxdraw_docs/graph/combination.html#%E5%A4%9A%E4%B8%AA%E5%9B%BE%E5%BD%A2%E7%BB%84%E5%90%88%E6%9E%84%E6%88%90%E4%B8%80%E4%B8%AA%E6%96%B0%E7%9A%84%E5%9B%BE%E5%BD%A2%E5%AF%B9%E8%B1%A1

Demo源码: https://github.com/mxcad/mxdraw-article/tree/master/%E5%AE%9E%E7%8E%B0%E4%B8%80%E7%A7%8D%E7%BB%98%E5%88%B6%E5%9C%86%E5%BC%A7%E7%9A%84%E6%96%B9%E5%BC%8F/demo


更多关于HarmonyOS鸿蒙Next中H5在线CAD实现一种绘制圆弧的方式的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS鸿蒙Next中,H5在线CAD实现绘制圆弧的方式可以通过使用Canvas API来实现。Canvas是HTML5提供的一个用于绘制图形的元素,支持2D图形绘制。以下是实现绘制圆弧的基本步骤:

  1. 创建Canvas元素:在HTML中创建一个Canvas元素,并设置其宽度和高度。

    <canvas id="myCanvas" width="500" height="500"></canvas>
    
  2. 获取Canvas上下文:通过JavaScript获取Canvas的2D上下文对象。

    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
  3. 绘制圆弧:使用arc()方法绘制圆弧。arc()方法的参数包括圆心坐标(x, y)、半径、起始角度、结束角度以及是否逆时针绘制。

    ctx.beginPath();
    ctx.arc(250, 250, 100, 0, Math.PI / 2, false); // 绘制一个从0到90度的圆弧
    ctx.stroke();
    
  4. 设置样式:可以通过strokeStylelineWidth等属性设置线条的颜色和宽度。

    ctx.strokeStyle = 'blue';
    ctx.lineWidth = 5;
    
  5. 填充圆弧:如果需要填充圆弧,可以使用fill()方法。

    ctx.fillStyle = 'rgba(0, 0, 255, 0.5)';
    ctx.fill();
    

通过以上步骤,可以在HarmonyOS鸿蒙Next的H5在线CAD中实现绘制圆弧的功能。Canvas API提供了丰富的图形绘制功能,可以满足各种复杂的绘图需求。

更多关于HarmonyOS鸿蒙Next中H5在线CAD实现一种绘制圆弧的方式的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,通过H5实现在线CAD绘制圆弧,可以使用HTML5的Canvas API结合JavaScript。首先,创建Canvas元素并获取2D上下文,然后使用arc()方法定义圆弧的圆心、半径、起始角度和结束角度。通过beginPath()开始路径,调用arc()绘制圆弧,最后使用stroke()fill()方法渲染。示例代码如下:

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI / 2, false); // 圆心(100,100),半径50,0到90度
ctx.stroke();

此方法适用于在H5页面中实现简单的圆弧绘制。

回到顶部