How to calculate the z-distance of a camera to view an image at 100% of its original scale in 3D space

How to calculate the distance of a camera from an object in 3D space (image in this case) so that the image has its original pixel width.

Am I correct in assuming that this is possible given the aspect ratio of the camera, fov and the original width / height of the image in pixels?

(In case this is relevant, I am using THREE.js in this particular case).

Thanks to everyone who can help or guide me in the right direction!

+3


source to share


3 answers


Thanks everyone for coming in!

After some digging and then figuring out how this all fits into the exact problem I'm trying to solve with THREE.js, this was the answer I came up with in JavaScript as a target distance Z to render things at their original scale:



var vFOV = this.camera.fov * (Math.PI / 180), // convert VERTICAL fov to radians

var targetZ = window.innerHeight / (2 * Math.tan(vFOV / 2) );

      

I was trying to figure out which one to mark as an answer, but I kind of combined them all in this solution.

+5


source


-trigonometric:

A linear segment of length l at right angles to the viewing plane and at a distance n perpendicular to it will substitute arctan (l / n) degrees to the camera. You can arrive at this result with simple trigonometry.

Hence, if your field of view in the direction of the line is q, which is p pixels, you end up occupying p*arctan(l/n)/q

pixels.

So, using y as the output number of pixels:

y = p*arctan(l/n)/q
y*q/p = arctan(l/n)
l/tan(y*q/p) = n

      

Linear algebra:

In a camera with a 90-degree field of view and a 2W wide viewing space, projection into screen space is equivalent to:



x' = w - w*x/z

      

If perpendicular to the line length on the screen, this is the difference between two such xs, so using the usual associativity and commutation rules:

l' = w - w*l/z

      

Hence:

w - l' = w*l/z
z = (w - l') / (w*l)

      

If your field of view is indeed q degrees rather than 90, you can use the cotangent to scale accordingly.

+2


source


In your original question, you said you are using css3D. I suggest you do the following:

Set up the spell camera with fov = 1..179 degrees, where left = screenWidth / 2, right = screenWidth / - 2, top = screenHeight / 2, bottom = screenHeight / - 2. The near and far planes do not affect CSS3D rendering, as much as I can tell from experience.

camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);
camera.fov = 75;

      

now you need to calculate the distance between the camera and the object so that when projecting the object with the camera with the settings above, the object has a 1: 1 coordinate on the screen. This can be done as follows:

var camscale = Math.tan(( camera.fov / 2 ) / 180 * Math.PI);
var camfix = screenHeight / 2 / camscale;

      

  • put your div at position: x, y, z
  • set camera position to 0, 0, z + camfix

This should give you a 1: 1 coordinate with your result and your pixel values ​​in the css / div styles. Remember that the origin is at the center and the position of the object is the center of the object, so you need to make adjustments to get the coordinate characteristics in the upper left corner, for example

object.x = ( screenWidth - objectWidth ) / 2 + positionLeft
object.y = ( screenHeight - objectHeight ) / 2 + positionTop
object.z = 0

      

Hope this helps, I was struggling with the same (fine css3d scene control) but managed to figure out that orthographic camera size + viewport size adjusted the distance from the object. Don't change the camera rotation or its x and y coordinates, just play with z and you are safe.

0


source







All Articles