Come adattare la fotocamera all’object

Usando three.js ho il seguente.

  • Una scena contenente diverse istanze Object3D
  • Diverse posizioni predefinite della videocamera vettoriale3
  • Una larghezza / altezza dynamic della canvas se lo schermo viene ridimensionato
  • Un utente può selezionare un object (dall’alto)
  • Un utente può selezionare una posizione della telecamera (dall’alto)

Dato che un object è stato visto e la posizione della telecamera, hanno scelto come calcolare la posizione finale della telecamera per “meglio adattarla” all’object sullo schermo?

Se le posizioni della telecamera vengono utilizzate “così come sono” su alcuni schermi, gli oggetti sanguinano oltre il bordo della mia vista, mentre altri appaiono più piccoli. Credo che sia ansible adattare l’object al trofeo della fotocamera, ma non è stato ansible trovare nulla di adatto.

Suppongo che tu stia usando una telecamera prospettica.

È ansible impostare la posizione della telecamera, il campo visivo o entrambi.

Il seguente calcolo è esatto per un object che è un cubo, quindi pensa in termini di riquadro di delimitazione dell’object, allineato per affrontare la telecamera.

Se la fotocamera è centrata e si vede il cubo frontalmente, definire

dist = distance from the camera to the _closest face_ of the cube 

e

 height = height of the cube. 

Se si imposta il campo visivo della telecamera come segue

 fov = 2 * Math.atan( height / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees 

quindi l’altezza del cubo corrisponderà all’altezza visibile.

A questo punto, è ansible aumentare leggermente la videocamera o aumentare leggermente il campo visivo.

Se il campo di vista è fisso, utilizzare l’equazione precedente per risolvere la distanza.


MODIFICA: se si desidera che la width del cubo corrisponda alla larghezza visibile, lasciare che l’ aspect sia il rapporto tra larghezza e altezza della canvas (larghezza della canvas divisa per altezza) e impostare il campo visivo della telecamera in questo modo

 fov = 2 * Math.atan( ( width / aspect ) / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees 

three.js r.69

In base alla risposta WestLangleys, ecco come calcoli la distanza con un campo visivo fisso della telecamera:

 dist = height / 2 / Math.tan(Math.PI * fov / 360); 

Per calcolare quanto lontano posizionare la tua fotocamera per adattare un object allo schermo, puoi usare questa formula (in Javascript):

 // Convert camera fov degrees to radians var fov = camera.fov * ( Math.PI / 180 ); // Calculate the camera distance var distance = Math.abs( objectSize / Math.sin( fov / 2 ) ); 

Dove objectSize è l’altezza o la larghezza dell’object. Per gli oggetti cubo / sfera puoi usare l’altezza o la larghezza. Per un object non-cube / non-sphere, dove lunghezza o larghezza è maggiore, utilizzare var objectSize = Math.max( width, height ) per ottenere il valore più grande.

Notare che se la posizione dell’object non è 0, 0, 0 , è necessario regolare la posizione della telecamera per includere l’offset.

Ecco un CodePen che mostra questo in azione. Le linee pertinenti:

 var fov = cameraFov * ( Math.PI / 180 ); var objectSize = 0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) ); var cameraPosition = new THREE.Vector3( 0, sphereMesh.position.y + Math.abs( objectSize / Math.sin( fov / 2 ) ), 0 ); 

Puoi vedere che se prendi la maniglia della finestra e la ridimensiona, la sfera occupa ancora il 100% dell’altezza dello schermo. Inoltre, l’object viene scalato in alto e in basso in modo sinusoidale ( 0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) ) ), per mostrare che la posizione della videocamera prende in considerazione la scala dell’object.

Dal suggerimento di user151496 sull’uso delle proporzioni, sembra funzionare, anche se ho provato solo con alcuni set di parametri diversi.

 var maxDim = Math.max(w, h); var aspectRatio = w / h; var distance = maxDim/ 2 / aspectRatio / Math.tan(Math.PI * fov / 360);