将笛卡尔宽度和高度转换为等距

时间:2015-07-23 02:10:49

标签: c++ height width sdl isometric

我正在尝试在SDL图形库中创建等距游戏。

在SDL中渲染时,需要源矩形和目标矩形。源矩形是您要加载的纹理部分,目标矩形是您要渲染的屏幕上的区域。矩形只包含4个属性,X位置,Y位置,宽度和高度。

现在说我有一个带有这些坐标的笛卡尔目标矩形:

  

X = 20,Y = 10,宽度= 16,高度= 16

现在说我想将其转换为Isometric。要转换X和Y坐标,我会使用:

isometricX = cartX - cartY;
isometricY = (cartX + cartY) / 2;

现在我不明白的是我要做的是将笛卡尔宽度和高度转换为等距宽度和高度,以创建视口移动45度到一侧和向下30度的幻觉,创建等距外观。

编辑: 我想稍微澄清一下我的问题,所以当我将笛卡尔坐标转换为等距时我改变了这个:http://i.stack.imgur.com/I79yK.png 对此:http://i.stack.imgur.com/ZCJg1.png。所以现在我想弄清楚如何旋转瓷砖,使它们全部融合在一起,以及我需要如何调整高度和宽度才能实现这一点。

2 个答案:

答案 0 :(得分:0)

不幸的是我不能发表评论要求澄清所以我必须回答一个问题:你能否转换所有四个点然后从这些点计算转换点的宽度和高度?

  

X = 20,Y = 10,宽度= 16,高度= 16

正如你所说

isometricX = cartX - cartY;
isometricY = (cartX + cartY) / 2;

所以

isometricX1 = cartX1 - cartY1;
isometricY1 = (cartX1 + cartY1) / 2;

isometricWidth = std::abs(isometricY - isometricY1)

虽然可能是更有效的路线,但由于我不知道笛卡尔几何,我无法找到解决方案

编辑 isometricWidth发现两点之间的距离不是宽度和高度 另一个注意事项是你需要对角(是的我觉得另一个人可能是一个更好的答案:P)

答案 1 :(得分:0)

首先,您需要这些操作来转换为等长坐标:

isoX = carX + carY;
isoY = carY - carX / 2.0;

carX = (isoX - isoY) / 1.5;
carY = isoX / 3.0 + isoY / 1.5;

左上角和右下角的直角变为120度,另外两个角变为60度。右下角成为底角,左上角成为顶部。这也假设y增加上升,x增加向右(如果你的系统不同,则相应地翻转符号)。您可以通过替换验证这些操作是否相反。

对于一个矩形,您需要转换4个点 - 角落 - 因为它们不是“矩形”用于SDL(它将是平行四边形)。这在数字上更容易看到。

首先,指定某种角落名称。我喜欢顺时针从左下角开始 - 这个坐标应该被称为C1,并且有一个关联的X1和Y1,其他的将是C2-4。

C2 - C3
|    |
C1 - C4

然后计算他们的笛卡尔坐标...

X1 = RECT.X;
Y1 = RECT.Y;

X2 = X1; // moving vertically
Y2 = RECT.Y + RECT.HEIGHT;

X3 = RECT.X + RECT.WIDTH;
Y3 = Y2; // moving horizontally

X4 = X3; // moving vertically
Y4 = RECT.Y;

最后将变换分别应用于每个坐标,以获得I1,I2,I3,I4坐标......

iX1 = X1 + Y1;
iY1 = Y1 - X1 / 2.0;
// etc

你最终得到的是屏幕坐标I1-4,它采用这种形状:

    I2
  /    \
I1      I3
  \    /
    I4

但与这种劣质描述不同,I4和I2的角度约为127度,而I1和I3的角度应为~53度。 (这可以精确调整为60/120,并且在计算isoY时取决于carX的2.0因子 - 它应该是sqrt(3)而不是2.0但是meh,足够接近)

如果使用逆变换,可以将I1-4坐标转回C1-4,或者从屏幕坐标等定位世界坐标。

如果只是在开始时实现一个摄像头/视口会有点棘手,但它超出了所要求的范围,所以我不会去那里(没有进一步的刺激)......

(编辑)关于SDL ......

SDL似乎与广义变换“玩得不好”。我没有使用它,但它的界面非常类似于GDI(windows),我之前玩过游戏引擎并遇到了这个问题(旋转+缩放纹理)。

有一个(看起来是非标准的)SDL功能同时进行纹理的缩放和旋转,但是它以错误的顺序执行,因此它始终保持图像的透视,这不是这里需要的

正如您所见,基本几何图形会很好,因为它的填充和线条不需要缩放,只能定位。但是对于纹理......您将不得不编写代码以一次渲染纹理一个像素,或者使用变换的组合(旋转后缩放)或分层(绘制alpha遮罩等距方块和渲染预先计算的纹理)等等......

当然,如果它是您的选择,请使用适合原始几何和纹理数据的内容,如OpenGL / Direct3D。就个人而言,我会选择使用OpenGL / SFML。