Почему камера.Посмотрите, когда камера находится в (0, 0, 0), говоря, что она поворачивается на -90 градусов вокруг оси, чтобы смотреть на (1, 0, 0)?

#graphics #three.js #3d #camera

#графика #three.js #3D #камера

Вопрос:

Смотрите Здесь Скрипку: https://jsfiddle.net/pkaru0xn/12 /

   box.position.set(1, 0, 0);

  var camera = new THREE.PerspectiveCamera();
  camera.position.set(0, 0, 0);
  camera.lookAt(box.position);
 

Я помещаю куб в (1, 0, 0). Камера расположена в (0, 0, 0). Согласно three.js если камера смотрит вниз, это локальная отрицательная ось z.

Поэтому я ожидал бы, что, если посмотреть на куб, он повернется на 90 градусов относительно оси y. Почему функция lookat возвращает -90 градусов? Почему это работает?

Комментарии:

1. Прочитайте о правостороннем правиле, поскольку оно применяется к правой системе координат. Это скажет вам, какое направление вращения положительное, а какое отрицательное.

2. Спасибо за ответ. Я знаю, что в three js используется правосторонняя система координат, при этом вектор (0, 1, 0) по умолчанию равен up. Как показано на моем чертеже, при этом я бы ожидал, что поворот для просмотра на (1, 0, 0) от прямого взгляда вниз (0, 0, -1) будет равен 90 градусам, а не -90.

Ответ №1:

Первоначально пространство камеры выровнено с мировым пространством. Это означает, что камера находится в (0, 0, 0) положении с вектором вверх (0, 1, 0) и смотрит вниз по -Z оси.

Правило правой руки приводит к вращению относительно против часовой стрелки. Это означает, что вращение вокруг Y оси с положительным значением приведет к перемещению взгляда камеры к -X оси. Присвоение углу поворота отрицательного значения приведет к тому, что взгляд камеры переместится к X оси.

Приведенный ниже код использует оба lookAt и rotateOnAxis для изменения поворота камеры. Обратите внимание, что взгляд на объект слева соответствует положительному углу поворота.

 const renderer = new THREE.WebGLRenderer({antialias: true, alpha: true})
document.body.appendChild(renderer.domElement)
renderer.setSize(200, 200)
renderer.setClearColor(0x55ccff)

const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(28, 1, 1, 1000)

const geo = new THREE.SphereBufferGeometry(10, 32, 32)

const leftMat = new THREE.MeshBasicMaterial({color:"red"})
const rightMat = new THREE.MeshBasicMaterial({color:"blue"})
const frontMat = new THREE.MeshBasicMaterial({color:"green"})

const left = new THREE.Mesh(geo, leftMat)
left.position.set(-50, 0, 0)
const right = new THREE.Mesh(geo, rightMat)
right.position.set(50, 0, 0)
const front = new THREE.Mesh(geo, frontMat)
front.position.set(0, 0, -50)

const light = new THREE.PointLight(0xffffff, 1)

scene.add(left, right, light, front, camera)

function render(){
  renderer.render(scene, camera)
}
render()

document.getElementById("reset").addEventListener("click", ()=>{
  camera.lookAt(front.position)
  render()
})

document.getElementById("leftLook").addEventListener("click", ()=>{
  camera.lookAt(left.position)
  render()
})
document.getElementById("rightLook").addEventListener("click", ()=>{
  camera.lookAt(right.position)
  render()
})

const axis = new THREE.Vector3().set(0, 1, 0)
document.getElementById("leftTurn").addEventListener("click", ()=>{
  camera.rotateOnAxis(axis, Math.PI / 2)
  render()
})
document.getElementById("rightTurn").addEventListener("click", ()=>{
  camera.rotateOnAxis(axis, Math.PI / -2)
  render()
}) 
 .test input {
  width: 150px;
}
.right {
  float: right;
}
.test {
  width: 100%;
}
.test:after {
  content: "amp;nbsp;"
  clear: both;
}
canvas {
  margin-left: auto;
  margin-right: auto;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script>
<div class="test">
<input id="leftLook" type="button" value="LEFT" /><input id="rightLook" type="button" value="RIGHT" />
</div>
<div class="test">
<input id="leftTurn" type="button" value="LEFT" /><input id="rightTurn" type="button" value="RIGHT" />
</div>
<input id="reset" type="button" value="RESET" /><br />