在笛卡尔坐标和屏幕坐标之间进行转换

use*_*947 13 c++ algorithm math coordinates coordinate-systems

对于我的游戏,我需要在两个坐标系之间进行转换的功能.那么它主要是数学问题,但我需要的是C++代码,以及如何解决我的问题的一些解释.

屏幕坐标:

a)左上角是0,0

b)没有负值

c)右+ = x(x值越多,右边越多是点)

d)底部+ = y

笛卡尔2D坐标:

a)中间点是(0,0)

b)确实存在负值

c)右+ = x

d)bottom - = y(y越小,底部越多)

我需要一种简单的方法从一个系统转换到另一个系统,反之亦然.要做到这一点,(我认为)我需要一些知识,比如放置在笛卡尔坐标系中的(0,0)[屏幕坐标左上角].

然而,对于在将其转换为屏幕坐标之后的笛卡尔坐标中的某些点存在的问题,屏幕坐标中的位置可能是负的,这是无意义的.我不能把屏幕坐标的左上角放在(-inifity,+ infinity)笛卡尔坐标中......

我怎么解决这个问题?我能想到的唯一解决方案是将屏幕(0,0)放在笛卡尔(0,0)中,并且仅使用IV四分之一的笛卡尔系统,但在这种情况下使用笛卡尔系统是没有意义的......

我确信有一些方法可以将屏幕坐标转换为笛卡尔坐标,反之亦然,但我在思考这个负值时做错了什么.

Mer*_*OWA 15

从笛卡尔坐标转换为屏幕坐标的基本算法是

screenX = cartX + screen_width/2
screenY = screen_height/2 - cartY
Run Code Online (Sandbox Code Playgroud)

但正如您所提到的,笛卡尔空间是无限的,而您的屏幕空间则不是.这可以通过改变屏幕空间和笛卡尔空间之间的分辨率来轻松解决.上述算法使得笛卡尔空间中的1个单位=屏幕空间中的1个单位/像素.如果您允许其他比率,您可以"缩放"或在屏幕空间中覆盖所有必需的笛卡尔空间.

这会将上述算法改为

screenX = zoom_factor*cartX + screen_width/2
screenY = screen_height/2 - zoom_factor*cartY
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过修改缩放系数来处理负(或过大)screenX和screenY,直到所有笛卡尔坐标都适合屏幕.

您也可以允许平移坐标空间,这意味着允许笛卡尔空间的中心偏离屏幕中心.这也可以帮助您使zoom_factor保持尽可能紧,同时也适合不均匀分布在笛卡尔空间原点周围的数据.

这会将算法更改为

screenX = zoom_factor*cartX + screen_width/2 + offsetX
screenY = screen_height/2 - zoom_factor*cartY + offsetY
Run Code Online (Sandbox Code Playgroud)


Dan*_*ker 5

您需要知道屏幕的宽度和高度。

然后你可以这样做:

cartX =   screenX - (width / 2);
cartY = -(screenY - (height / 2));
Run Code Online (Sandbox Code Playgroud)

和:

screenX =  cartX + (width / 2);
screenY = -cartY + (height / 2);
Run Code Online (Sandbox Code Playgroud)


sgo*_*lez 5

您必须知道屏幕的大小才能进行转换

转换为笛卡尔:

cartesianx = screenx - screenwidth / 2;
cartesiany = -screeny + screenheight / 2;
Run Code Online (Sandbox Code Playgroud)

转换为屏幕:

screenx = cartesianx + screenwidth / 2;
screeny = -cartesiany + screenheight / 2;
Run Code Online (Sandbox Code Playgroud)

对于负屏幕值的情况:我不会担心这一点,该内容将被简单地剪裁,因此用户将看不到。如果这一个问题,我会添加一些约束以防止笛卡尔坐标过大。另一个解决方案,因为你不能让边缘为 +/- 无穷大,所以将缩放你的坐标(例如 1 像素 = 10 笛卡尔)让我们称之为scalefactor. 现在的方程是:

使用比例因子转换为笛卡尔坐标:

cartesianx = scalefactor*screenx - screenwidth / 2;
cartesiany = -scalefactor*screeny + screenheight / 2;
Run Code Online (Sandbox Code Playgroud)

使用比例因子转换为屏幕:

screenx = (cartesianx + screenwidth / 2) / scalefactor;
screeny = (-cartesiany + screenheight / 2) / scalefactor;
Run Code Online (Sandbox Code Playgroud)