En utilisant three.js, j'ai ce qui suit.
Compte tenu de la visualisation d'un objet et de la position de la caméra, ils ont choisi comment calculer la position finale de la caméra pour "adapter au mieux" l'objet à l'écran?
Si les positions de la caméra sont utilisées "telles quelles" sur certains écrans, les objets saignent sur le bord de ma fenêtre tandis que d'autres apparaissent plus petits. Je pense qu'il est possible d'adapter l'objet au tronc de la caméra, mais je n'ai rien trouvé de convenable.
Je suppose que vous utilisez une caméra en perspective.
Vous pouvez définir la position de la caméra, le champ de vision ou les deux.
Le calcul suivant est exact pour un objet qui est un cube, pensez donc en termes de boîte englobante de l'objet, alignée pour faire face à la caméra.
Si la caméra est centrée et regarde le cube de face, définissez
dist = distance from the camera to the _closest face_ of the cube
et
height = height of the cube.
Si vous définissez le champ de vision de la caméra comme suit
fov = 2 * Math.atan( height / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees
alors la hauteur du cube correspondra à la hauteur visible.
À ce stade, vous pouvez sauvegarder un peu la caméra ou augmenter légèrement le champ de vision.
Si le champ de vision est fixe, utilisez l'équation ci-dessus pour résoudre la distance.
EDIT: si vous voulez que le cube width
corresponde au visible largeur, laissez aspect
être le rapport d'aspect du canevas (largeur du canevas divisée par la hauteur du canevas), et définir le champ de vision de la caméra comme
fov = 2 * Math.atan( ( width / aspect ) / ( 2 * dist ) ) * ( 180 / Math.PI ); // in degrees
three.js r.69
Sur la base de la réponse de WestLangleys, voici comment calculer la distance avec un champ de vision de caméra fixe:
dist = height / 2 / Math.tan(Math.PI * fov / 360);
Pour calculer la distance à laquelle placer votre appareil photo pour adapter un objet à l'écran, vous pouvez utiliser cette formule (en 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 ) );
Où objectSize
est la hauteur ou la largeur de l'objet. Pour les objets cube/sphère, vous pouvez utiliser la hauteur ou la largeur. Pour un objet non cube/non sphère, où la longueur ou la largeur est supérieure, utilisez var objectSize = Math.max( width, height )
pour obtenir la plus grande valeur.
Notez que si la position de votre objet n'est pas à 0, 0, 0
, Vous devez ajuster la position de votre caméra pour inclure le décalage.
Voici un CodePen montrant cela en action. Les lignes concernées:
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
);
Vous pouvez voir que si vous saisissez la poignée de la fenêtre et la redimensionnez, la sphère occupe toujours 100% de la hauteur de l'écran. De plus, l'objet évolue vers le haut et vers le bas de manière sinusoïdale (0.6 + ( 0.5 * Math.sin( Date.now() * 0.001 ) )
), pour montrer que la position de la caméra prend en compte l'échelle de l'objet.
D'après la suggestion de user151496 concernant l'utilisation du rapport d'aspect, cela semble fonctionner, même si je n'ai testé qu'avec quelques jeux de paramètres différents.
var maxDim = Math.max(w, h);
var aspectRatio = w / h;
var distance = maxDim/ 2 / aspectRatio / Math.tan(Math.PI * fov / 360);
essayez ceci pour OrbitControls
let padding = 48;
let w = Math.max(objectLength, objectWidth) + padding;
let h = objectHeight + padding;
let fovX = camera.fov * (aspectX / aspectY);
let fovY = camera.fov;
let distanceX = (w / 2) / Math.tan(Math.PI * fovX / 360) + (w / 2);
let distanceY = (h / 2) / Math.tan(Math.PI * fovY / 360) + (w / 2);
let distance = Math.max(distanceX, distanceY);