C++ 在二维坐标中放大到屏幕的中心 [英] C++ Zoom into the centre of the screen in 2D coordinates

查看:26
本文介绍了C++ 在二维坐标中放大到屏幕的中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难进行正确的计算,以便在 2D 坐标中放大屏幕中心,同时将所有内容保持在正确的比例.

I'm having difficulty working out the correct calculations in order to zoom into the centre of the screen in 2D coordinates whilst keeping everything in the correct scale.

我有一个矢量,用于处理在我的地图编辑器中移动,如下所示:

I have a vector which I use to handle moving around my map editor as follows:

scroll = sf::Vector2<float>(-640.0f, -360.0f);

它设置为 -640.0f, -360.0f 以在初始化时使 0,0 成为屏幕的中心(基于我的窗口为 1280x720).

It's set at -640.0f, -360.0f to make 0,0 the centre of the screen on initialising (based on my window being 1280x720).

我的缩放值范围从 0.1f 到 2.0f,并且以 0.05 的增量增加或减少:

My zoom value ranges from 0.1f to 2.0f and it's increased or decreased in 0.05 increments:

zoomScale = zoomScale + 0.05;

在屏幕上绘制元素时,它们是使用以下代码绘制的:

When drawing elements on to the screen they are drawn using the following code:

sf::Rect<float> dRect;
dRect.left = (mapSeg[i]->position.x - scroll.x) * (layerScales[l] * zoomScale);
dRect.top = (mapSeg[i]->position.y - scroll.y) * (layerScales[l] * zoomScale);
dRect.width = (float)segDef[mapSeg[i]->segmentIndex]->width;
dRect.height = (float)segDef[mapSeg[i]->segmentIndex]->height;

sf::Sprite segSprite;
segSprite.setTexture(segDef[mapSeg[i]->segmentIndex]->tex);
segSprite.setPosition(dRect.left, dRect.top);
segSprite.setScale((layerScales[l] * zoomScale), (layerScales[l] * zoomScale));
segSprite.setOrigin(segDef[mapSeg[i]->segmentIndex]->width / 2, segDef[mapSeg[i]->segmentIndex]->height / 2);
segSprite.setRotation(mapSeg[i]->rotation);
Window.draw(segSprite);

layerScales 是用于按比例放大段层以进行视差滚动的值.

layerScales is a value used to scale up layers of segments for parallax scrolling.

这在放大和缩小时似乎工作正常,但中心点似乎发生了变化(我知道应该始终位于 0,0 的元素将在我放大后立即位于不同的坐标处).我使用以下来计算鼠标的位置来测试如下:

This seems to work fine when zooming in and out but the centre point seems to shift (an element that I know should always be at 0,0 will be located at different co-ordinates as soon as I zoom). I use the following to calculate what the position as at the mouse to test this as follows:

mosPosX = ((float)input.mousePos.x + scroll.x) / zoomScale)
mosPosY = ((float)input.mousePos.y + scroll.y) / zoomScale)

我确定我应该对滚动"向量进行计算以将这种缩放考虑在内,但我似乎无法让它正常工作.

I'm sure there's a calculation I should be doing to the 'scroll' vector to take into account this zoom but I can't seem to get it to work right.

我尝试实现类似下面的内容,但没有产生正确的结果:

I tried implementing something like below but it didn't produce the correct results:

scroll.x = (scroll.x - (SCREEN_WIDTH / 2)) * zoomScale - (scroll.x - (SCREEN_WIDTH / 2));
scroll.y = (scroll.y - (SCREEN_HEIGHT / 2)) * zoomScale - (scroll.y - (SCREEN_HEIGHT / 2));

知道我做错了什么吗?

推荐答案

我会用简单的方法(效率不高但效果很好)并且只针对单轴(第二个是相同的)

I will do this the easy way (not most efficient but works fine) and only for single axis (second is the same)

最好不缩放偏移量:

scaledpos = (unscaledpos*zoomscale)+scrolloffset

知道比例变化后中心点不应该移动(0表示之前1表示之后):

know center point should not move after scale change (0 means before 1 means after):

scaledpos0 == scaledpos1

这样做:

scaledpos0 = (midpointpos*zoomscale0)+scrolloffset0; // old scale
scaledpos1 = (midpointpos*zoomscale1)+scrolloffset0; // change zoom only
scrolloffset1+=scaledpos0-scaledpos1;                  // correct offset so midpoint stays where is ... i usualy use mouse coordinate instead of midpoint so i zoom where the mouse is 

当你不能改变缩放方程时,就用你的一样

when you can not change the scaling equation then just do the same with yours

scaledpos0 = (midpointpos+scrolloffset0)*zoomscale0;
scaledpos1 = (midpointpos+scrolloffset0)*zoomscale1;
scrolloffset1+=(scaledpos0-scaledpos1)/zoomscale1;

希望我在那里没有犯愚蠢的错误(凭记忆写).欲了解更多信息,请参阅

Hope I did no silly error in there (writing from memory). For more info see

这篇关于C++ 在二维坐标中放大到屏幕的中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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