1

我正在尝试在 three.js 中创建一个小型交互式 UFO 绕地球飞行的场景。

我认为最好在地图的 2D 投影(如小地图)上控制 UFO,将像素坐标转换为 lat/lng 坐标,最后将 lat/lng 转换为可用于 3D 场景的向量。

事实证明,事实并非如此。

如果 UFO 绕赤道飞行(+/- 几度),效果很好,但可以肯定的是,我忘记将投影应用于我的 2D 控件:

在此处输入图像描述

现在我有点迷路了。我的控件(WASD 键)基本上设置了小地图上 UFO 的速度和旋转,但我必须为播放器添加某种“校正”。这就是目前设置值的方式:

let left = parseFloat(this.minimapPlayer.style.left) + this.speed * Math.cos(Math.PI / 180 * this.rotation)
let top = parseFloat(this.minimapPlayer.style.top) + this.speed * Math.sin(Math.PI / 180 * this.rotation)

有没有办法创造一个“真实”的轨道,这样我的 UFO 就不会总是飞过两极?或者是否有更好的方法来处理 UFO 的轨道(可能没有小地图)?

到目前为止,这是完整的动画代码:

animatePlane(firstRender) {
  requestAnimationFrame(this.animatePlane)

  // set next position
  let left = parseFloat(this.minimapPlayer.style.left) + this.speed * Math.cos(Math.PI / 180 * this.rotation)
  let top = parseFloat(this.minimapPlayer.style.top) + this.speed * Math.sin(Math.PI / 180 * this.rotation)

  // handle border collisions
  if (left < 0) {
    left = this.minimapBounds.width
  }

  if (left > this.minimapBounds.width) {
    left = 0
  }

  if (top < 0 || top > this.minimapBounds.height) {
    this.rotation = this.rotation * -1

    if (this.rotation > 0) {
      this.plane.up.set(0, 1, 0)
    } else {
      this.plane.up.set(0, -1, 0)
    }

    top = top + this.speed * Math.sin(Math.PI / 180 * this.rotation)

    if (left < this.minimapBounds.width / 2) {
      left = left + this.speed * Math.cos(Math.PI / 180 * this.rotation) + this.minimapBounds.width / 2
    } else {
      left = left + this.speed * Math.cos(Math.PI / 180 * this.rotation) - this.minimapBounds.width / 2
    }
  }

  this.minimapPlayer.style.left = `${left}px`
  this.minimapPlayer.style.top = `${top}px`

  // convert to lat/lng
  const lat = (180 / this.minimapBounds.height) * (top - this.minimapBounds.height / 2) * -1
  const lng = (360 / this.minimapBounds.width) * (left - this.minimapBounds.width / 2)

  // convert to vector
  const p = this.latLongToVector3(lat, lng, this.radius, 200)
  this.plane.position.set(p.x, p.y, p.z)

  // bottom of the plane should always look the the middle of the earth
  this.plane.lookAt(new THREE.Vector3(0,0,0))
}
4

0 回答 0