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

标签 c++ height width sdl isometric

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

当您在 SDL 中渲染时,您需要一个源矩形和一个目标矩形。源矩形是您已加载并希望渲染的纹理部分,而目标矩形是您要渲染到的屏幕区域。矩形仅包含 4 个属性,X 位置、Y 位置、宽度和高度。

现在假设我有一个具有这些坐标的笛卡尔目标矩形:

X=20, Y=10, Width=16, Height=16

现在假设我想将其转换为等轴测图。要转换 X 和 Y 坐标,我将使用:

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

现在我不明白的是,我将如何将笛卡尔宽度和高度转换为等轴测宽度和高度,以产生视口(viewport)向一侧移动 45 度并向下移动 30 度的错觉,从而创建等距外观。

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

最佳答案

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

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 但嗯,足够接近了)

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

如果只是一开始,实现相机/视口(viewport)会有点棘手,但它超出了要求,所以我不会去那里(没有进一步的刺激)......

(编辑)关于 SDL...

SDL 似乎不能“很好地处理”广义转换。我没有使用过它,但它的界面与我之前为游戏引擎玩过的 GDI (windows) 非常相似,但遇到了这个确切的问题(旋转 + 缩放纹理)。

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

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

当然,如果您愿意,也可以使用适合原始几何体和纹理数据的工具,例如 OpenGL/Direct3D。就我个人而言,我会选择 OpenGL/SFML 来做这样的事情。

关于c++ - 将笛卡尔宽度和高度转换为等距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31577053/

相关文章:

html - 如何在 HTML/CSS 中设置百分比高度值

html - css - 行数的最小高度

html - 文本比最大宽度表列宽

html - 宽度自动不会居中

c++ - 为什么函数指针定义可以使用任意数量的与号 '&' 或星号 '*' ?

c++ - 如何在函数内部创建一个数组,然后使用该数组创建另一个数组?

c++ - 声明和初始化指针到指针字符数组

c++ - 从 native iOS C 代码访问所有环境变量

css - 如何使 Bootstrap .card-img-top 在响应宽度下等高?

javascript - 计算span的scrollWidth,offsetWidth,clientWidth的值