如何定位相机以使对象在屏幕上始终具有相同的像素宽度和高度?

2022-01-14 00:00:00 geometry math javascript three.js

我有一个问题我不知道如何解决,也许有人可以给我一个提示.

I have a problem I don't know how to go about solving, maybe someone can give me a hint on how to solve it.

我希望将相机定位在 z 索引处,这将导致立方体以完全相同的像素宽度和高度显示,无论窗口的大小或纵横比是多少.立方体的 z 位置为 0.需要将相机放置在后面看这个立方体.

I want the camera to be positioned at a z index which will result in the cube being shown at exactly the same pixel width and height no matter what the size or aspect ratio of the window is. The cube is at a z position of 0. The camera needs to be positioned back looking at this cube.

因此,当用户看到屏幕显示时,用户应该会在屏幕上看到具有完全相同像素宽度和高度的立方体.现在我猜测相机的z位置一定是窗口宽度、高度、纵横比和常数的函数.

So when the user sees the screen display, the user should see the cube having the exact same pixel width and height on their screen. Now I guess that the camera z position must be a function of the window width, height, aspect ratio and a constant.

如何计算 A、B、C 和 D?我怀疑这是一个几何问题,但我不知道如何解决它.也许我需要添加一个约束条件,即对象在匹配 100 像素宽和 100 像素高的像素中应具有完全相同的宽度和高度.

How can I calculate A, B, C and D? I suspect this is a geometry problem but I don't know how to go about solving it. Perhaps I need to add the constraint that the object should have exactly the same width and height in pixels matching 100 pixels wide and 100 pixels high.

var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new PerspectiveCamera( 60.0, aspectRatio, 1.0, 10000.0 );

var A = 1.0;
var B = 1.0;
var C = 1.0;
var D = 1.0;
camera.position.z = A * window.innerWidth + B * window.innerHeight +
                    (C * aspectRatio) + D;
var geometry = new CubeGeometry( 100.0, 100.0, 0.0001 );

<小时>

更新,我通过反复试验解决了它.


Update, I solved it with trial and error.

我不了解这个的几何形状或数学,但我注意到对象的大小取决于窗口的高度,而不是取决于窗口的宽度.同样,我不知道为什么,但是当我调整高度时,对象变得更大或更小,但是当我调整宽度时,对象保持不变.

I don't understand the geometry of this or the maths of this, but what I did was I noticed that the objects size was dependant on the height of the window and not dependant on the width of the window. Again, I don't know why, but when I resized the height, the object became bigger or smaller but when I resized the width the object stayed the same.

所以我决定高度可能是决定功能的一个元素,然后我通过改变值进行反复试验,直到我得到正确的大小,大小为 100 x 100 像素.然后我改变了高度,它保持相同的大小.我很高兴我有这个结果.

So I decided its likely the height is the one element which determines the function and then I used trial and error by varying values until I got it at the right size, 100 by 100 pixels in size. Then I varied the height and it stayed the same size. I'm so happy I have this result.

num A = 0.0;
num B = -0.867;
num C = 0.0;
num D = 0.0;

推荐答案

在你的情况下更可能依赖于较小的窗口大小轴!因为纵横比方程通常因情况而异:

In your case is more likely dependent on the smaller window size axis !!! because aspect ratio equations usually differs for cases:

  1. 宽度>高度
  2. 宽度 <高度

大多数渲染都采用了 OpenGL 的这种行为,因此您的代码可能需要添加一个 if 才能完成 :).确保将窗口的大小调整为高度大于宽度,然后看看会发生什么

most renders have taken this behavior from OpenGL so may be your code needs adding one if to be complete :). To be sure just resize your window to be bigger in height then width and see what happens

顺便说一句.背后的数学只是简单的三角形数学,如下所示:

btw. the math behind is just simple triangle math like this:

一个 angle = 90 度 第二个是

atan (h1/z1) = atan (h0/z0)
h1/z1 = h0/z0   <- triangle similarity
z1 = z0*h1/h0   <- this is what you want

在哪里:
h0 是控制轴的一半大小(xy)
h1 是立方体大小的一半
z0 靠近你的视锥体平面
z1 是立方体位置(别忘了加上立方体中心的偏移量)

Where:
h0 is your half size in control axis (x or y)
h1 is half cube size
z0 is near plane of your frustrum
z1 is cube position (do not forget to add the offset to center of cube)

所以立方体中心位置是:

so cube center position is:

z1' = (z0*h1/h0)+h1

相关文章