将笛卡尔宽度和高度转换为等轴测图 [英] convert Cartesian width and height to Isometric

查看:160
本文介绍了将笛卡尔宽度和高度转换为等轴测图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在SDL图形库中创建一个Isometric游戏.

I'm trying to create an Isometric game in the SDL graphics library.

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

When you render in SDL you require a source rectangle and a destination rectangle. The source rectangle is the portion of the texture you have loaded that you wish to render and the destination rectangle is the area on the screen you are rendering to. Rectangles simply consist of 4 properties, X position, Y position, Width, and Height.

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

Now say I have a Cartesian destination rectangle with these coordinates:

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

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

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

Now say I wanted to convert this to Isometric. To convert the X and Y coordinates I would use:

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

现在,我不了解的是我将笛卡尔的宽度和高度转换为等轴测宽度和高度时会产生的错觉,即视口向一侧移动了45度,向下移动了30度,从而产生了一种错觉.等距外观.

Now what I don't understand is what I would do to convert the Cartesian Width and Height to Isometric Width and Height to create the illusion that the view port is being moved 45 degrees to one side and 30 degrees down, creating the Isometric look.

我想澄清一下我的问题,所以当我将笛卡尔坐标转换为等轴测时,我将其更改为: http://i.stack.imgur.com/I79yK.png 为此: http://i.stack.imgur.com/ZCJg1.png .因此,现在我试图弄清楚如何旋转磁贴,使它们全部契合在一起,以及如何调整高度和宽度以使这种情况发生.

I'd like to clarify my question a little, so when I convert the Cartesian Coordinates to Isometric I change this:http://i.stack.imgur.com/I79yK.png to this:http://i.stack.imgur.com/ZCJg1.png. So now I am trying to figure out how to rotate the tiles so they all fit together and how I need to adjust the Height and Width to get this to happen.

推荐答案

首先,您需要执行以下操作以与等轴坐标进行相互转换:

To start with you'll need these operations to convert to and from isometric coordinates:

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

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

左上角和右下角的

直角拐角变为120度,其他两个拐角变为60度.右下角变为下角,左上角变为顶部.这还假设y沿上升方向增加,x沿向右方向增加(如果您的系统不同,请相应地翻转符号).您可以通过替换来验证这些操作彼此相反.

right-angled corners in the top-left and bottom-right become 120 degrees, the other two corners become 60 degrees. the bottom-right corner becomes the bottom corner, the top-left corner becomes the top. this also assumes that y increases going up, and x increases going right (if your system is different, flip the signs accordingly). you can verify via substitution that these operations are eachothers inverse.

对于一个矩形,您需要转换4个点-角-因为就SDL而言,它们将不是矩形"(它将是平行四边形).用数字更容易看到它.

for a rectangle you need 4 points transformed - the corners - as they will not be 'rectangular' for the purposes of SDL (it will be a parallelogram). this is easier to see numerically.

首先,分配某种拐角名称.我更喜欢从左下角开始顺时针旋转-此坐标应称为C1,并具有关联的X1和Y1,其他坐标为C2-4.

first, assign the corners names of some sort. i prefer clockwise starting with the bottom-left - this coordinate shall be known as C1, and has an associated X1 and Y1, the others will be C2-4.

C2 - C3
|    |
C1 - C4

然后计算其笛卡尔坐标...

then compute their cartesian coordinates...

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坐标...

and lastly apply the transform individually to each coordinate, to get I1, I2, I3, I4 coordinates...

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

最后得到的是屏幕坐标I1-4,其形状如下:

and what you end up with is on-screen coordinates I1-4, that take this shape:

    I2
  /    \
I1      I3
  \    /
    I4

但是与这种伪劣的描述不同,I4和I2的角度约为127度,而I1和I3的角度约为53度. (可以将其微调为恰好为60/120,并在计算isoY时取决于carX的2.0因子-应该是sqrt(3)而不是2.0,但应足够接近)

But unlike this shoddy depiction, the angles for I4 and I2 will be ~127 deg, and for I1 and I3 it should be ~53 deg. (this could be fine-tuned to be exactly 60/120, and depends on the 2.0 factor for carX when computing isoY - it should be sqrt(3) rather than 2.0 but meh, close enough)

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

if you use the inverse transform, you can turn back the I1-4 coordinates into C1-4, or locate a world coordinate from a screen coordinate etc.

如果只是一开始,实现摄像头/视口会有些棘手,但这超出了要求,所以我不会去那里(没有进一步的建议)...

implementing a camera / viewport gets a little tricky if only at first but it's beyond what was asked so i won't go there (without further prodding)...

(编辑)关于SDL ...

在通用转换中,SDL似乎不能很好地播放".我没有使用过它,但是它的界面与我之前在游戏引擎中玩过的GDI(窗口)非常相似,并遇到了这个确切的问题(旋转+缩放纹理).

SDL does not appear to "play nice" with generalized transforms. I haven't used it but its interface is remarkably similar to GDI (windows) which I've played around with for a game engine before and ran into this exact issue (rotating + scaling textures).

有一个(看起来是非标准的)SDL函数既可以缩放纹理又可以旋转纹理,但是它以错误的顺序进行,因此它始终保持图像的透视图,而这不是必需的

There is one (looks to be non-standard) SDL function that does both scaling and rotating of textures, but it does it in the wrong order so it always maintains the perspective of the image, and that's not what is needed here.

基本几何形状会很好,因为它不需要填充即可填充和填充线,只需定位即可.但是对于纹理...您将不得不要么编写代码以一次渲染一个像素,要么使用变换(旋转后缩放)的组合,或者分层(绘制带有alpha蒙版的等距正方形并进行渲染)预先计算的纹理)等等...

Basic geometry will be fine, as you've seen, because it's fills and lines which don't need to be scaled, only positioned. But for textures... You're going to have to either write code to render the texture one pixel at a time, or use a combination of transforms (scale after rotate), or layering (drawing an alpha-masked isometric square and rendering a pre-computed texture) and so on...

或者当然,如果您可以选择使用,则使用适合原始几何和纹理数据的工具,例如OpenGL/Direct3D.就我个人而言,我会使用OpenGL/SFML这样的东西.

Or of course, if it's an option for you, use something suited for raw geometry and texture data like OpenGL / Direct3D. Personally I'd go with OpenGL / SFML for something like this.

这篇关于将笛卡尔宽度和高度转换为等轴测图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆