【问题标题】:Aframe/Three fit to screen - calculate zoomAframe/Three 适合屏幕 - 计算缩放
【发布时间】:2021-05-28 08:59:26
【问题描述】:

我想将相机缩放到三帧/一帧,以便图像适合屏幕。

这是我正在使用的代码:

    this._camera = document.getElementById('camera').getAttribute('camera')
    this._ratio = this._assetWidth/this._assetHeight

    this._vFOV = window.THREE.Math.degToRad( this._camera?.fov || 80 )

    this._height = 2 * Math.tan( this._vFOV / 2 ) * this.data.distance
    this._width = this._height * this._ratio

    this._zoom = this._ratio > 1 ? this._width/window.innerWidth : this._height/window.innerHeight

    console.log(this._zoom,  this._ratio, this._width, window.innerWidth)

我已经到了需要计算缩放以使对象适合屏幕的部分,即如果它的横向适合宽度,如果它的纵向适合高度。

我以为this was the answer 但不是。那是计算相机位置而不是缩放值。

我不知道你是如何计算缩放值的。

有什么线索吗?

【问题讨论】:

    标签: math three.js webgl aframe quaternions


    【解决方案1】:

    通过以下方式使对象适应屏幕:

    • 更改相机 FoV
    • 缩放相机
    • 重新定位相机/对象

    一旦您了解公式的来源,就会非常相似。
    我们将使用这张简洁的图片 (from this SO thread),因为它涵盖了所有三个主题:

    0。我们想要实现什么

    我们希望对象(其宽度或高度的较长边)覆盖filmHeight - 使其适合屏幕。

    1.重新计算 FoV

    在这种情况下,我们确实知道focalLength(相机与对象的距离)和filmHeight(对象宽度或高度)。感谢我们的朋友trigonometry,我们可以计算fov / 2

    Tan (fov / 2) = (filmHeight / 2) / focalLength
    => fov = 2 * ATan ((filmHeight / 2)) / focalLength * 180 / PI

    <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
    <script>
      AFRAME.registerComponent("fit", {
        init: function() {
          const plane = document.querySelector("a-plane")
          const distance = this.el.object3D.position.distanceTo(plane.object3D.position)
          var height = plane.getAttribute("geometry").height
          var newFov = 2 * Math.atan((height / 2) / distance) * (180 / Math.PI); // in degrees
          this.el.sceneEl.camera.fov = newFov
        }
      })
    </script>
    <a-scene>
      <a-plane position="0 1.6 -2" material="src: https://i.imgur.com/wjobVTN.jpg"></a-plane>
      <a-camera position="0 1.6 0" fit></a-camera>
    </a-scene>

    2。重新定位对象/相机

    相同的三角形不同的变量。现在我们想知道focalLength:
    Tan (fov / 2) = (filmHeight / 2) / focalLength
    =&gt; focalLength = (filmHeight / 2) / Tan (fov / 2)

    <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
    <script>
      AFRAME.registerComponent("fit", {
        init: function() {
          const plane = document.querySelector("a-plane")
          const height = plane.getAttribute("geometry").height
          const fov = this.el.sceneEl.camera.fov * (Math.PI / 180);
          const newDistance = Math.abs((height / 2) / Math.tan(fov / 2))
          plane.object3D.position.z = -1 * newDistance;
        }
      })
    </script>
    <a-scene>
      <a-plane position="0 1.6 -2" material="src: https://i.imgur.com/wjobVTN.jpg"></a-plane>
      <a-camera position="0 1.6 0" fit></a-camera>
    </a-scene>

    3.缩放相机

    如果我们知道相机应该与对象之间的距离以使其充​​满屏幕 - 我们就知道当前距离与新距离之间的关系是什么:

    zoom = currentDistance / necessaryDistance

    <script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
    <script>
      AFRAME.registerComponent("fit", {
        init: function() {
          const plane = document.querySelector("a-plane");
          const distance = this.el.object3D.position.distanceTo(plane.object3D.position);
          const height = plane.getAttribute("geometry").height;
          const fov = this.el.sceneEl.camera.fov * (Math.PI / 180);
          const newDistance = Math.abs((height / 2) / Math.tan(fov / 2));
          this.el.sceneEl.camera.zoom = distance / newDistance;
        }
      })
    </script>
    <a-scene>
      <a-plane position="0 1.6 -2" material="src: https://i.imgur.com/wjobVTN.jpg"></a-plane>
      <a-camera position="0 1.6 0" fit></a-camera>
    </a-scene>

    【讨论】:

    • 由于a-frame 管理窗口/画布调整大小,我认为没有必要使用窗口宽度/高度。至少当我更改 fiddle 窗口大小时它似乎可以正常工作
    • 这是一个惊人的答案@Piotr
    • @beek 你没有任何评论就接受了答案,我担心它是“meh,good enogh”:D 如果它有帮助,我真的很高兴,实际上你的问题让我查找并尝试了解其背后的数学原理。
    • Stackoverflow 上的最佳答案!意味着我可以看到哪种解决方案效果最好并进行相应调整!非常感谢您的帮助!
    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多