【问题标题】:Cannot calculate 2D position from 3D co-ordinates无法从 3D 坐标计算 2D 位置
【发布时间】:2021-06-11 21:38:33
【问题描述】:

我正在使用 angular 和 three.js 从点云中选择顶点。我一直在尝试用其 x、y、z 信息标记选定的顶点。我一直在尝试使用这些资源:

  1. three.js Vector3 to 2D screen coordinate with rotated scene
  2. https://threejsfundamentals.org/threejs/lessons/threejs-align-html-elements-to-3d.html

我无法按照描述的那样工作。

我目前的代码是:

this.labels.forEach(element =>{
      const tempVertex = new THREE.Vector3(this.geometry.attributes.position.getX(element.index), 
                                          this.geometry.attributes.position.getY(element.index),
                                          this.geometry.attributes.position.getZ(element.index));


     
      let pointsMatrix = this.points.matrixWorld
      tempVertex.applyMatrix4(pointsMatrix);
      tempVertex.project(this.camera);

      let canvasBounds = this.renderer.domElement.getBoundingClientRect();

      const x = Math.round( (   tempVertex.x + 1 ) * canvasBounds.width / 2 );
      const y = Math.round( ( - tempVertex.y + 1 ) * canvasBounds.height / 2 );

      element.label.style.transform = `translate(${x}px,${y}px)`;
    });

它必须是计算,因为我总是以类似的数量出局:

我尝试混合和匹配不同的想法,因为我已经尝试过,并且屏幕截图与我所获得的一样接近。我只是不太了解数学,无法弄清楚。我知道这里有很多人这样做,有人可以告诉我我哪里错了。

我认为这可能与使用 pointCloud 对象获取世界矩阵有关,但这是我唯一的几何对象。如果有区别,则在创建 div 元素时不会设置位置。

 public createTextLabel(index: number){
    const elem = document.createElement('div');

    let x = this.geometry.attributes.position.getX(index);
    let y = this.geometry.attributes.position.getY(index);
    let z = this.geometry.attributes.position.getZ(index);

    elem.innerHTML = `X: ${x}<br> Y: ${y}<br> Z: ${z}`;

    this.labels.push({index: index, label: elem});
    this.hudContainer.nativeElement.appendChild(elem);
  }

【问题讨论】:

    标签: angular three.js


    【解决方案1】:

    这是我设法得到的最接近的:

    this.labels.forEach(element =>{
          const tempVertex = new THREE.Vector3(this.geometry.attributes.position.getX(element.index), 
                                              this.geometry.attributes.position.getY(element.index),
                                              this.geometry.attributes.position.getZ(element.index));
    
          let canvasBounds = this.renderer.domElement.getBoundingClientRect();
    
          this.camera.updateMatrixWorld
          tempVertex.project(this.camera);
    
          tempVertex.x =  (   tempVertex.x + 1 ) * (canvasBounds.width + canvasBounds.left) / 2 ;
          tempVertex.y =  ( - tempVertex.y + 1) * (canvasBounds.height - canvasBounds.top ) / 2 ;
      
          element.label.style.transform = `translate(-50%, -50%) translate(${tempVertex.x}px,${tempVertex.y}px)`;
        });
    

    两个基本问题:

    1. css 导致我之前的屏幕截图中的第二个标签较低。需要使用视图封装:没有让我的动态 div 样式化。
    2. 不包括从窗口到我的画布的间隙测量(不是全屏)

    虽然不完美,但现在已经足够了。

    【讨论】:

      猜你喜欢
      • 2014-04-09
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多