色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          "); //-->

          博客專欄

          EEPW首頁(yè) > 博客 > 在線CAD(mxdraw庫(kù))如何自定義一個(gè)等腰三角形

          在線CAD(mxdraw庫(kù))如何自定義一個(gè)等腰三角形

          發(fā)布人:MxDraw 時(shí)間:2024-03-14 來(lái)源:工程師 發(fā)布文章
          前言

          網(wǎng)頁(yè)CAD可以通過(guò)瀏覽器對(duì)DWG圖紙進(jìn)行交互和操作,用戶無(wú)需下載和安裝 CAD應(yīng)用程序,而是在Web界面上直接瀏覽、修改、交互和保存CAD圖紙。目前網(wǎng)頁(yè)版CAD已經(jīng)成為一種流行的設(shè)計(jì)工具,許多設(shè)計(jì)師和工程師都在使用它進(jìn)行設(shè)計(jì)工作,下面我們使用夢(mèng)想CAD云圖(H5在線CAD)完成一個(gè)自定義等腰三角形的圖形。

          寫一個(gè)等腰三角形的形狀類

          1.我們知道要構(gòu)成三角形一定是需要三個(gè)點(diǎn)的, 所以我們可以通過(guò)mxdraw庫(kù)提供的自定義形狀類MxDbShape擴(kuò)展出一個(gè)三角形。

          1)首先我們?cè)?/span>src/App.vue文件中找打<script setup></script>中的內(nèi)容繼續(xù)往下寫,代碼如下:

          import { MxDbShape } from "mxdraw"

          // ...其他內(nèi)容

          export class MxDbTriangle extends MxDbShape {

               // 這是必須的,這里相當(dāng)于增加了一個(gè)傳輸值 points屬性, 這個(gè)points就表示三個(gè)點(diǎn)的坐標(biāo)位置

               points: THREE.Vector3[] = []

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

              //  我們直接重寫getShapePoints 方法, 這樣就可以直接把三個(gè)點(diǎn)渲染出來(lái)了

              getShapePoints(): THREE.Vector3[] {

                  return this.points

              }

          }

          以上就是實(shí)現(xiàn)了一個(gè)普通三角形類, 只需要往points中添加3個(gè)點(diǎn),就會(huì)構(gòu)成一個(gè)三角形, 你也可以用其他屬性表示三角形的三個(gè)點(diǎn),比如point1、 point2 、point3;

          2)但是這個(gè)三角形只是一個(gè)靜態(tài)的三角形,你不能對(duì)三角形的三個(gè)點(diǎn)進(jìn)行移動(dòng),也不能移動(dòng)整個(gè)三角形;

          3)因此我們還可以再重寫幾個(gè)方法,讓它支持再畫布上移動(dòng)三角形或者構(gòu)成三角形的點(diǎn),代碼如下:

          import { MxDbShape } from "mxdraw"

          export class MxDbTriangle extends MxDbShape {

            // ...

            // 計(jì)算一下三角形的中間位置 這樣我們我們就可以通過(guò)中點(diǎn)控制整個(gè)三角形的位置

            getCenter() {

                  const _points = this.getShapePoints()

                  // 計(jì)算點(diǎn)的數(shù)量

                  const numPoints = _points.length;

                  // 計(jì)算所有點(diǎn)的向量之和

                  let sum = new THREE.Vector3();

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

                      sum.add(_points[i]);

                  }

                  const center = sum.divideScalar(numPoints);

                  return center

            }

            // 返回可以操作和移動(dòng)的多個(gè)點(diǎn)坐標(biāo), 只有知道要操作的點(diǎn)在上面位置才能進(jìn)行操作呀

             getGripPoints() {

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

              }

              // 這里就開(kāi)始移動(dòng)點(diǎn)的位置了 offset就是鼠標(biāo)點(diǎn)擊操作點(diǎn)后的偏移量, 我們就可以通過(guò)add的方式改變點(diǎn)的位置了

              // 那么如果是中點(diǎn)的話,我們就把三角形的三個(gè)點(diǎn)都進(jìn)行偏移, 這樣就實(shí)現(xiàn)移動(dòng)整個(gè)三角形的功能了

              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.有了三角形,那么我們?cè)偎伎嫉妊切问鞘裁礃拥哪? 以下只是其中一種實(shí)現(xiàn)方式,你也可以通過(guò)其他方式實(shí)現(xiàn)。

          1)首先等腰三角形也是三角形, 所以我們用三個(gè)點(diǎn)來(lái)表示等腰三角形的三個(gè)點(diǎn), 分別是底部開(kāi)始點(diǎn)和結(jié)束點(diǎn)以及頂點(diǎn)。

          2)我們需要先知道中點(diǎn),去計(jì)算這個(gè)三角形的高度, 然后通過(guò)三個(gè)點(diǎn)的位置關(guān)系確認(rèn)三角形的方向,最好得到三角形的實(shí)際頂點(diǎn)位置,代碼如下:

          // 等腰三角形

          export class MxDbIsoscelesTriangle extends MxDbTriangle {

              protected _propertyDbKeys = [...this._propertyDbKeys]

              getShapePoints() {

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

                  // 計(jì)算等腰三角形底邊的中點(diǎn)

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

                  // 計(jì)算高度和頂點(diǎn)位置

                  const height = topPoint.distanceTo(midpoint);

                  // 計(jì)算topPoint相對(duì)于baseStart和baseEnd的位置關(guān)系

                  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);

                  // 將三個(gè)點(diǎn)按照逆時(shí)針?lè)较蚺帕?/span>

                  const _points = [baseStart, baseEnd, vertex];

                  return _points;

              }

              getGripPoints() {

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

              }

          }

          以上就是實(shí)現(xiàn)一個(gè)等腰三角形的全部過(guò)程。

          3.那么我們要在畫布上畫出這個(gè)等腰三角形應(yīng)該如何實(shí)現(xiàn)呢?

          1)首先我們需要點(diǎn)擊一個(gè)按鈕, 表示開(kāi)始畫等腰三角形

          2)然后我們需要監(jiān)聽(tīng)canvas上的點(diǎn)擊事件, 并記錄點(diǎn)擊位置轉(zhuǎn)換成three.js坐標(biāo);

          3)最后將坐標(biāo)值添加到MxDbIsoscelesTriangle實(shí)例中。

          我們需要三個(gè)點(diǎn)的位置坐標(biāo),所以需要監(jiān)聽(tīng)三次點(diǎn)擊。上述步驟比較繁瑣, 為此mxdraw庫(kù)提供了MrxDbgUiPrPoint 來(lái)幫助我們簡(jiǎn)化上述步驟,代碼如下:

          // 等腰三角形

          export class MxDbIsoscelesTriangle extends MxDbTriangle {

              protected _propertyDbKeys = [...this._propertyDbKeys]

              getShapePoints() {

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

                  // 計(jì)算等腰三角形底邊的中點(diǎn)

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

                  // 計(jì)算高度和頂點(diǎn)位置

                  const height = topPoint.distanceTo(midpoint);

                  // 計(jì)算topPoint相對(duì)于baseStart和baseEnd的位置關(guān)系

                  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);

                  // 將三個(gè)點(diǎn)按照逆時(shí)針?lè)较蚺帕?/span>

                  const _points = [baseStart, baseEnd, vertex];

                  return _points;

              }

              getGripPoints() {

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

              }

          }

          4)我們將這個(gè)函數(shù)放在一個(gè)按鈕的點(diǎn)擊事件中,在App.vue<template></template>中繼續(xù)新增代碼:

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

          現(xiàn)在就可以看看畫等腰三角形的功能是否實(shí)現(xiàn)了,效果如下圖:

           

          試試點(diǎn)擊中間夾點(diǎn)移動(dòng)等腰三角形,效果如下圖:

           

          4.我們最后總結(jié)一下,首先需要先搭建一個(gè)在線CAD的網(wǎng)頁(yè),在網(wǎng)頁(yè)上可以繪制自定義的等腰三角形,其次需要Node環(huán)境、Vite前端工程化項(xiàng)目、使用mxdraw、對(duì)CAD圖紙進(jìn)行轉(zhuǎn)換、實(shí)現(xiàn)自定義形狀,而自定義形狀,我們先定義了三角形,又根據(jù)三角形定義了等腰三角形的類。在效果圖中,我們可以看見(jiàn)等腰三角形是有描邊效果和填充效果,這些都是自定義形狀的基類提供的功能,只需要設(shè)置對(duì)應(yīng)的屬性就可以實(shí)現(xiàn)對(duì)應(yīng)的效果。

          最后沒(méi)有問(wèn)題,我們可以通過(guò)在項(xiàng)目根目錄運(yùn)行命令:

          npm run build

          打包文件用打包線上的版本前端資源,在dist目錄中是具體打包后的代碼。

          *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



          關(guān)鍵詞: WEB CAD

          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉