threejs+angular 实现面积测量

本文介绍如何使用ThreeJS和Angular实现BIM轻量化平台中的面积测量功能,涉及点的碰撞检测、多边形拆分及三角形面积计算。通过鼠标交互完成测量,其中画线部分采用ThreeJS的MeshLine实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多bim轻量化平台应该都有测量这个功能,什么距离啊,角度测量呀,里面比较复杂的还是面积测量这块,其他就比较简单了;

首先面积测量你得考虑是否共面,还得兼容凹凸多边形 

先看看效果吧

逻辑很简单:1.只有模型才可以点击,空白的地方不能测量的(其实就是碰撞检测)2.鼠标抬起是确定一个点,鼠标移动是你绘制线 3.三个点确定一个平面 4.把任意多变形拆分成三角形来计算面积

实现逻辑都在这里,画线是用three的MeshLine画的,其实主要看面积测量逻辑就ok了,语言是ts写的,具体细节交流私下



@Injectable()
export class MeasureAreaService {
  private sprite = null;
  private line_measure = null;
  private currentPoint = null;
  private currentCount = 0;
  private firstPoint = null;
  private origin = null;
  private downTime = 0;
  private upTime = 0;
  private onmousemoveSubscription = null;
  private onmousedownSubscription = null;
  private onmouseupSubscription = null;
  private mousewheelSubscription = null;
  private needHighLightSubscription = null;
  private pointList = new Array < THREE.Vector3 > ();
  private keydownEvent = null;
  private aParameter = 0;
  private bParameter = 0;
  private cParameter = 0;
  private dParameter = 0;
  private measureItems: any[] = [];
  private dashedLine;
  public close() {
    if (this.onmousemoveSubscription) {
      this.onmousemoveSubscription.unsubscribe();
    }
    if (this.onmousedownSubscription) {
      this.onmousedownSubscription.unsubscribe();
    }
    if (this.onmouseupSubscription) {
      this.onmouseupSubscription.unsubscribe();
    }
    if (this.mousewheelSubscription) {
      this.mousewheelSubscription.unsubscribe();
    }
    if (this.needHighLightSubscription) {
      this.needHighLightSubscription.unsubscribe();
    }
    if (this.sprite) {
      this.viewerService.highlightScene.remove(this.sprite);
    }

    if (this.keydownEvent) {
      (window as any).removeEventListener('keydown', this.keydownEvent, false);
    }

    //this.state = OptState.Idle;
     this.clear();
     //this.rendererService.needHighLightRender.emit(true);
     this.measureItemsManagerService.close();
  }

  public open() {
    this.keydownEvent = (event) => {
      if (event.keyCode === 27) {
        if (this.currentCount >= 3) {
          if (this.currentPoint.x == this.firstPoint.x &&
            this.currentPoint.y == this.firstPoint.y &&
            this.currentPoint.z == this.firstPoint.z) {
            //防止闪烁
            if (this.measureItemsManagerService.getCurrentMeasureItem()) {
              this.measureItemsManagerService.deactiveCurrentMeasureLine();
            }
            //实例化线条
            this.measureItemsManagerService.getCurrentMeasureItem().active = true;
            this.measureItemsManagerService.createMeasureItem().active = true;
            
          } else {
            this.viewerService.highlightScene.remove(this.measureItemsManagerService.getCurrentMeasureItem().highlightLine.getHighlightLine());
            let highlightLine = new HighLightLine(this.measureItemsManagerService.getHighlightMaterial());
            let measureItem = this.measureItemsManagerService.createMeasureItem();
            measureItem.setHighlightLine(highlightLine);
            me
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值