获取缩放产生的相对于鼠标的偏移量

Get the offset produced by zoom relative to the mouse

我正在尝试实现一个具有鼠标缩放功能的 2D 游戏。 都是这样组织的:

游戏对象具有不受打印缩放或偏移影响的任意位置。 (并且随意,我选择从左上角的(0,0)开始每个级别,等于渲染引擎使用的)

游戏资产像素完美,需要在放大时保持原样。所以我用一个整数来表示缩放级别,缩放比例为2^zoom.

每个对象都由一个函数呈现在屏幕上,该函数使用其私有位置并采用缩放级别(整数)和表示偏移量的两个整数。

它打印将偏移量添加到它的坐标并将其全部乘以 2^zoom。

主循环基本上完成了所有的输入处理,然后是所有内部状态的更新,然后是渲染。 (照常) 所有的混乱都必须在更新部分内,因为渲染将只接受缩放级别以及 x 和 y 偏移量。

我尝试按照另一个问题的第一个答案来实现它: C++ Zoom into the centre of the screen in 2D coordinates 并以鼠标的位置而不是屏幕的中心作为坐标。

最让人头疼的是试图获得必须正确提供给渲染函数的偏移量。

目前相关的功能代码是这样的:

void PlayState::updateOffset(bool zoomIn, int zoomLevel, int MouseX, int MouseY){

float finalX, finalY, sF, scaledPosition0x;
float scaledPosition0y, scaledPosition1x, scaledPosition1y;

sF = pow(2,zoomLevel);

if(zoomIn){
    scaledPosition0x = MouseX*pow(2,zoomLevel-1)+xOffset;
    scaledPosition0y = MouseY*pow(2,zoomLevel-1)+yOffset;
}else{
    scaledPosition0x = MouseX*pow(2,zoomLevel+1)+xOffset;
    scaledPosition0y = MouseY*pow(2,zoomLevel+1)+yOffset;
} 

scaledPosition1x = MouseX*sF+xOffset;
scaledPosition1y = MouseY*sF+yOffset;

finalX = (scaledPosition0x-scaledPosition1x)/sF;
finalY = (scaledPosition0y-scaledPosition1y)/sF;

incrementOffset(finalX, finalY);}

增量偏移函数只是检查偏移量是否太大并进行更正。如您所见,它看起来像链接问题答案中的代码。它看起来像是提到的代码的复制粘贴,但我已经尝试实现许多('long long' 很多)其他方式,甚至对此进行了一些改动,并且 none 更接近预期结果。

目前,只要您将鼠标保持在 0,0,或者滚动指向从缩放级别 0 到 -1 或到 1 并返回到 0 的任意位置而不移动鼠标,它就会产生奇迹。任何其他缩放组合 level/position 都会呈现异常结果。

期待您的回答。我很乐意提供所需的任何其他详细信息。

已解决

我会 post 对我有用的答案,以防有人遇到同样的问题。

问题的关键在于偏移量的存储方式(未缩放)。

这有点奇怪,因为缩放是在代码的不同部分完成的,所以我们通常对矩阵执行的操作(撤消 - 操作 - 重做)是无效的。但是,如果让我了解要遵循的道路。

如图所示,首先要做的是撤消操作。也就是找到鼠标在未触及的场景中的位置(没有缩放也没有偏移)。

原场景鼠标位置为OMP。 屏幕中的鼠标位置将为 MP。 Z0 将是最后一帧应用的缩放。 Off0 将是我们在最后一帧的偏移量。

OMP = (MP-Off0*Z0)/Z0

然后我们对新的缩放进行逆运算,所以我们看看如果我们现在取消缩放,缩放会在哪里结束*,后者和前者之间的差异会给我们偏差。

Off1 = MP/Z1 - OMP

*:如果我们不撤消偏移量,当前偏移量将自动保留,所以稍后我们将一个替换另一个,不需要从之前的偏移量add/substract