将xyz投影到xy屏幕坐标的功能

时间:2018-11-29 13:45:53

标签: java c++ 3d geometry coordinates

您好,我正在尝试使用商用2D游戏开发引擎来创建2D / 3D混合游戏。

游戏将具有一系列2D子画面,这些子画面将根据其在伪3D空间中的深度显示在屏幕上,而不仅仅是如图所示的x和y位置。

enter image description here

如果子画面“ A”在500宽,500高度和500深度的世界中的x,y,z(150,20,100)点处,应在1024x768分辨率屏幕上将其绘制在何处?

我无法深入了解3D屏幕投影的深入理论,就像这里和互联网上的大多数解决方案一样。只是当精灵位于xyz点时,精灵中心应该在屏幕上的位置的基本知识。

考虑到插图中的场景,有人可以协助我提供所需的逻辑吗?就像使用任何语言(甚至是伪代码)的函数一样,该函数都会在将x,y,z参数传递给X和Y对之后返回X和Y对。

谢谢

1 个答案:

答案 0 :(得分:0)

如果您想要最简单的代码并且不想陷入矩阵中,请尝试如下操作:

Vec2 screenCenter = Vec2( screensize.x/2, screensize.y/2 ); // half of your screen resolution
                                                            // try changing it to see what happens
                                                            // you can animate it to add special effects
float perspStrength = 500.0f;   // actually an inverse of perspective strength
                                // lower values means bigger effect

Vec2 project( Vec3 pos )        // projection code
{
    Vec2 localPos = pos - screenCenter; // Move point (0,0) to the center of your screen

    float scale = pos.z/perspStrength;  // scale your Z to ~(0-1) range
    scale += 1.0f;                      // move your Z to ~(1-2) range

    localPos.x /= scale;                // scale position according to Z distance
    localPos.y /= scale;

    Vec2 result = localPos + screenCenter;  // Move point (0,0) back to the corner

    return result;
//    return Vec3( result.x, result.y, scale ); // you can also return scale used for this object
                                                // so you can render distant objects as smaller
}

我写了这段代码,假设它将与浮点值一起使用。我之所以选择500,是因为您假设Z在(0,500)范围内,所以我想将其移至(0-1)范围。我们不希望在投影代码中包含0,因为我们将除以该值,所以我们添加1将比例移到(1-2)范围。随时更改这些值,看看会发生什么。

根据您的第二个问题: 我认为您使用int重写了此代码,因此除以500会取消Z=100的值,并且其结果与Z=100向量相同。要修复它,您可以将int更改为float,并且都应该没问题。如果您不希望或不能这样做,并且需要int的代码,则需要稍作更改:

我们可以使用int代替浮点比例尺,并以1/1000单位表示比例尺,因此基本比例尺将为1000。

获取秤的最简单方法:

int scale = 1000 - pos.z;

如果需要缩放透视效果,则可以使用以下方法:

int perspStrength = 100;
int scale = 1000 - (pos.z*perspStrength/100);

现在,当您以scale单位使用1/1000时,可以缩放向量:

localPos.x = localPos.x * scale / 1000;
localPos.y = localPos.y * scale / 1000;