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

新手上路,请多包涵

对于我的游戏,我需要在两个坐标系之间转换的函数。嗯,这主要是数学问题,但我需要的是 C++ 代码来做这件事,以及如何解决我的问题的一些解释。

屏幕坐标:

a) 左上角是 0,0

b) 没有负值

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

d) 底部 +=y

笛卡尔二维坐标:

a) 中点为 (0, 0)

b) 负值确实存在

c) 右 += x

d) 底部 -= y (y 越少,底部越多)

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

但是存在一个问题,笛卡尔坐标中的某个点在转换为屏幕坐标后,屏幕坐标中的位置可能是负数,这是胡说八道。我不能将屏幕坐标的左上角放在(-inifity,+infinity)笛卡尔坐标中……

我该如何解决这个问题?我能想到的唯一解决方案是将屏幕 (0, 0) 放在笛卡尔 (0, 0) 中,并且只使用笛卡尔系统的四分之一,但在这种情况下,使用笛卡尔系统毫无意义……

我确信有办法将屏幕坐标转换为笛卡尔坐标,反之亦然,但我的想法是用负值做错了。

原文由 user1873947 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

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

screenX = cartX + screen_width/2
screenY = screen_height/2 - cartY

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

这会将上述算法更改为

screenX = zoom_factor*cartX + screen_width/2
screenY = screen_height/2 - zoom_factor*cartY

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

您也可以允许平移坐标空间,这意味着允许笛卡尔空间的中心偏离屏幕中心。这也有助于让您的 zoom_factor 保持尽可能紧凑,但也适合未均匀分布在笛卡尔空间原点周围的数据。

这会将算法更改为

screenX = zoom_factor*cartX + screen_width/2 + offsetX
screenY = screen_height/2 - zoom_factor*cartY + offsetY

原文由 MerickOWA 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

转换为笛卡尔:

 cartesianx = screenx - screenwidth / 2;
cartesiany = -screeny + screenheight / 2;

转换为屏幕:

 screenx = cartesianx + screenwidth / 2;
screeny = -cartesiany + screenheight / 2;

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

转换为具有比例因子的笛卡尔:

 cartesianx = scalefactor*screenx - screenwidth / 2;
cartesiany = -scalefactor*screeny + screenheight / 2;

转换为具有比例因子的屏幕:

 screenx = (cartesianx + screenwidth / 2) / scalefactor;
screeny = (-cartesiany + screenheight / 2) / scalefactor;

原文由 sgonzalez 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题