将笛卡尔宽度和高度转换为等距
convert Cartesian width and height to Isometric
我正在尝试在 SDL 图形库中创建一个等距游戏。
当您在 SDL 中渲染时,您需要一个源矩形和一个目标矩形。源矩形是您已加载并希望渲染的纹理部分,而目标矩形是您要渲染到的屏幕区域。矩形仅包含 4 个属性,X 位置、Y 位置、宽度和高度。
现在假设我有一个具有这些坐标的笛卡尔目标矩形:
X=20, Y=10, Width=16, Height=16
现在假设我想将其转换为等轴测图。要转换 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。所以现在我想弄清楚如何旋转瓷砖,使它们都适合在一起,以及我需要如何调整高度和宽度才能实现这一点。
不幸的是,我不能评论要求澄清,所以我必须回答一个问题:你不能转换所有四个点,然后从这些点计算转换点的宽度和高度吗?
X=20, Y=10, Width=16, Height=16
如你所说
isometricX = cartX - cartY;
isometricY = (cartX + cartY) / 2;
所以
isometricX1 = cartX1 - cartY1;
isometricY1 = (cartX1 + cartY1) / 2;
和
isometricWidth = std::abs(isometricY - isometricY1)
虽然可能有更有效的路线,但由于我不了解笛卡尔几何,所以找不到该解决方案
EDITisometricWidth 发现两点之间的距离不是宽度和高度
另一个注意事项是你需要对角(是的,我意识到另一个人可能是一个更好的答案:P)
首先,您需要这些操作来转换等距坐标:
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 个点 t运行sformed - 角 - 因为它们不会 'rectangular' 用于 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;
最后将 t运行sform 单独应用于每个坐标,以获得 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 但嗯,足够接近了)
如果使用逆t运行s形式,可以将I1-4坐标转回C1-4,或者从屏幕坐标定位世界坐标等
如果只是一开始,实现相机/视口会有点棘手,但它超出了要求,所以我不会去那里(没有进一步的刺激)...
(编辑)关于 SDL...
SDL 似乎 "play nice" 具有广义的 t运行 形式。我没有使用过它,但它的界面与我之前为游戏引擎玩过的 GDI (windows) 非常相似,并且 运行 进入了这个确切的问题(旋转 + 缩放纹理)。
有一个(看起来是非标准的)SDL 函数可以同时缩放和旋转纹理,但它以错误的顺序执行,所以它始终保持图像的透视,但那不是这里需要。
如您所见,基本几何图形就可以了,因为填充和线条不需要缩放,只需定位。但是对于纹理......你将不得不编写代码来一次渲染一个像素的纹理,或者使用 t运行sforms 的组合(旋转后缩放),或者分层(绘制 alpha -masked isometric square and rendering a pre-computed texture) 等等...
或者,当然,如果您愿意,可以使用适合原始几何图形和纹理数据的工具,例如 OpenGL/Direct3D。就我个人而言,我会使用 OpenGL / SFML 来做这样的事情。
我正在尝试在 SDL 图形库中创建一个等距游戏。
当您在 SDL 中渲染时,您需要一个源矩形和一个目标矩形。源矩形是您已加载并希望渲染的纹理部分,而目标矩形是您要渲染到的屏幕区域。矩形仅包含 4 个属性,X 位置、Y 位置、宽度和高度。
现在假设我有一个具有这些坐标的笛卡尔目标矩形:
X=20, Y=10, Width=16, Height=16
现在假设我想将其转换为等轴测图。要转换 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。所以现在我想弄清楚如何旋转瓷砖,使它们都适合在一起,以及我需要如何调整高度和宽度才能实现这一点。
不幸的是,我不能评论要求澄清,所以我必须回答一个问题:你不能转换所有四个点,然后从这些点计算转换点的宽度和高度吗?
X=20, Y=10, Width=16, Height=16
如你所说
isometricX = cartX - cartY;
isometricY = (cartX + cartY) / 2;
所以
isometricX1 = cartX1 - cartY1;
isometricY1 = (cartX1 + cartY1) / 2;
和
isometricWidth = std::abs(isometricY - isometricY1)
虽然可能有更有效的路线,但由于我不了解笛卡尔几何,所以找不到该解决方案
EDITisometricWidth 发现两点之间的距离不是宽度和高度 另一个注意事项是你需要对角(是的,我意识到另一个人可能是一个更好的答案:P)
首先,您需要这些操作来转换等距坐标:
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 个点 t运行sformed - 角 - 因为它们不会 'rectangular' 用于 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;
最后将 t运行sform 单独应用于每个坐标,以获得 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 但嗯,足够接近了)
如果使用逆t运行s形式,可以将I1-4坐标转回C1-4,或者从屏幕坐标定位世界坐标等
如果只是一开始,实现相机/视口会有点棘手,但它超出了要求,所以我不会去那里(没有进一步的刺激)...
(编辑)关于 SDL...
SDL 似乎 "play nice" 具有广义的 t运行 形式。我没有使用过它,但它的界面与我之前为游戏引擎玩过的 GDI (windows) 非常相似,并且 运行 进入了这个确切的问题(旋转 + 缩放纹理)。
有一个(看起来是非标准的)SDL 函数可以同时缩放和旋转纹理,但它以错误的顺序执行,所以它始终保持图像的透视,但那不是这里需要。
如您所见,基本几何图形就可以了,因为填充和线条不需要缩放,只需定位。但是对于纹理......你将不得不编写代码来一次渲染一个像素的纹理,或者使用 t运行sforms 的组合(旋转后缩放),或者分层(绘制 alpha -masked isometric square and rendering a pre-computed texture) 等等...
或者,当然,如果您愿意,可以使用适合原始几何图形和纹理数据的工具,例如 OpenGL/Direct3D。就我个人而言,我会使用 OpenGL / SFML 来做这样的事情。