新闻  |   论坛  |   博客  |   在线研讨会
在线CAD(mxdraw库)如何自定义一个等腰三角形
MxDraw | 2024-03-14 15:35:26    阅读:64   发布文章

前言

网页CAD可以通过浏览器对DWG图纸进行交互和操作,用户无需下载和安装 CAD应用程序,而是在Web界面上直接浏览、修改、交互和保存CAD图纸。目前网页版CAD已经成为一种流行的设计工具,许多设计师和工程师都在使用它进行设计工作,下面我们使用梦想CAD云图(H5在线CAD)完成一个自定义等腰三角形的图形。

写一个等腰三角形的形状类

1.我们知道要构成三角形一定是需要三个点的, 所以我们可以通过mxdraw库提供的自定义形状类MxDbShape扩展出一个三角形。

1)首先我们在src/App.vue文件中找打<script setup></script>中的内容继续往下写,代码如下:

import { MxDbShape } from "mxdraw"

// ...其他内容

export class MxDbTriangle extends MxDbShape {

     // 这是必须的,这里相当于增加了一个传输值 points属性, 这个points就表示三个点的坐标位置

     points: THREE.Vector3[] = []

     protected _propertyDbKeys = [...this._propertyDbKeys, "points"]

    //  我们直接重写getShapePoints 方法, 这样就可以直接把三个点渲染出来了

    getShapePoints(): THREE.Vector3[] {

        return this.points

    }

}

以上就是实现了一个普通三角形类, 只需要往points中添加3个点,就会构成一个三角形, 你也可以用其他属性表示三角形的三个点,比如point1、 point2 、point3;

2)但是这个三角形只是一个静态的三角形,你不能对三角形的三个点进行移动,也不能移动整个三角形

3)因此我们还可以再重写几个方法,让它支持再画布上移动三角形或者构成三角形的点,代码如下:

import { MxDbShape } from "mxdraw"

export class MxDbTriangle extends MxDbShape {

  // ...

  // 计算一下三角形的中间位置 这样我们我们就可以通过中点控制整个三角形的位置

  getCenter() {

        const _points = this.getShapePoints()

        // 计算点的数量

        const numPoints = _points.length;

        // 计算所有点的向量之和

        let sum = new THREE.Vector3();

        for (let i = 0; i < numPoints; i++) {

            sum.add(_points[i]);

        }

        const center = sum.divideScalar(numPoints);

        return center

  }

  // 返回可以操作和移动的多个点坐标, 只有知道要操作的点在上面位置才能进行操作呀

   getGripPoints() {

        return [...this.points, this.getCenter()]

    }

    // 这里就开始移动点的位置了 offset就是鼠标点击操作点后的偏移量, 我们就可以通过add的方式改变点的位置了

    // 那么如果是中点的话,我们就把三角形的三个点都进行偏移, 这样就实现移动整个三角形的功能了

    moveGripPointsAt(index: number, offset: THREE.Vector3): boolean {

        if (index === 3) {

            this.points = [this.points[0].clone().add(offset), this.points[1].clone().add(offset), this.points[2].clone().add(offset)]

        } else {

            this.points[index] = this.points[index].clone().add(offset)

        }

        return true

    }

}

2.有了三角形,那么我们再思考等腰三角形是什么样的呢? 以下只是其中一种实现方式,你也可以通过其他方式实现。

1)首先等腰三角形也是三角形, 所以我们用三个点来表示等腰三角形的三个点, 分别是底部开始点和结束点以及顶点。

2)我们需要先知道中点,去计算这个三角形的高度, 然后通过三个点的位置关系确认三角形的方向,最好得到三角形的实际顶点位置,代码如下:

// 等腰三角形

export class MxDbIsoscelesTriangle extends MxDbTriangle {

    protected _propertyDbKeys = [...this._propertyDbKeys]

    getShapePoints() {

        const [baseStart, baseEnd, topPoint] = this.points

        // 计算等腰三角形底边的中点

        const midpoint = baseStart.clone().add(baseEnd).multiplyScalar(0.5);

        // 计算高度和顶点位置

        const height = topPoint.distanceTo(midpoint);

        // 计算topPoint相对于baseStart和baseEnd的位置关系

        const baseVector = new THREE.Vector3().subVectors(baseEnd, baseStart).normalize();

        const perpendicularVector = new THREE.Vector3().crossVectors(baseVector, new THREE.Vector3(0, 0, 1)).normalize();

        const direction = new THREE.Vector3().subVectors(topPoint, midpoint).dot(perpendicularVector);

        const vertex = midpoint.clone().addScaledVector(perpendicularVector, direction >= 0 ? height : -height);

        // 将三个点按照逆时针方向排列

        const _points = [baseStart, baseEnd, vertex];

        return _points;

    }

    getGripPoints() {

        return [...this.getShapePoints(), this.getCenter()]

    }

}

以上就是实现一个等腰三角形的全部过程。

3.那么我们要在画布上画出这个等腰三角形应该如何实现呢?

1)首先我们需要点击一个按钮, 表示开始画等腰三角形

2)然后我们需要监听canvas上的点击事件, 并记录点击位置转换成three.js坐标

3)最后将坐标值添加到MxDbIsoscelesTriangle实例中。

我们需要三个点的位置坐标,所以需要监听三次点击。上述步骤比较繁琐, 为此mxdraw库提供了MrxDbgUiPrPoint 来帮助我们简化上述步骤,代码如下:

// 等腰三角形

export class MxDbIsoscelesTriangle extends MxDbTriangle {

    protected _propertyDbKeys = [...this._propertyDbKeys]

    getShapePoints() {

        const [baseStart, baseEnd, topPoint] = this.points

        // 计算等腰三角形底边的中点

        const midpoint = baseStart.clone().add(baseEnd).multiplyScalar(0.5);

        // 计算高度和顶点位置

        const height = topPoint.distanceTo(midpoint);

        // 计算topPoint相对于baseStart和baseEnd的位置关系

        const baseVector = new THREE.Vector3().subVectors(baseEnd, baseStart).normalize();

        const perpendicularVector = new THREE.Vector3().crossVectors(baseVector, new THREE.Vector3(0, 0, 1)).normalize();

        const direction = new THREE.Vector3().subVectors(topPoint, midpoint).dot(perpendicularVector);

        const vertex = midpoint.clone().addScaledVector(perpendicularVector, direction >= 0 ? height : -height);

        // 将三个点按照逆时针方向排列

        const _points = [baseStart, baseEnd, vertex];

        return _points;

    }

    getGripPoints() {

        return [...this.getShapePoints(), this.getCenter()]

    }

}

4)我们将这个函数放在一个按钮的点击事件中,在App.vue<template></template>中继续新增代码:

<button @click="drawTriangle">绘制等腰三角形</button>

现在就可以看看画等腰三角形的功能是否实现了,效果如下图:

 

试试点击中间夹点移动等腰三角形,效果如下图:

 

4.我们最后总结一下,首先需要先搭建一个在线CAD的网页,在网页上可以绘制自定义的等腰三角形,其次需要Node环境、Vite前端工程化项目、使用mxdraw、对CAD图纸进行转换、实现自定义形状,而自定义形状,我们先定义了三角形,又根据三角形定义了等腰三角形的类。在效果图中,我们可以看见等腰三角形是有描边效果和填充效果,这些都是自定义形状的基类提供的功能,只需要设置对应的属性就可以实现对应的效果。

最后没有问题,我们可以通过在项目根目录运行命令:

npm run build

打包文件用打包线上的版本前端资源,在dist目录中是具体打包后的代码。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客