C++ Zoom into the centre of the screen in 2D coordinates

别说谁变了你拦得住时间么 提交于 2019-12-31 06:42:15

问题


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);

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).

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 is a value used to scale up layers of segments for parallax scrolling.

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));

Any ideas what I'm doing wrong?


回答1:


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

it is better to have offset unscaled:

scaledpos = (unscaledpos*zoomscale)+scrolloffset

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

scaledpos0 == scaledpos1

so do this:

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

  • Zooming graphics based on current mouse position


来源:https://stackoverflow.com/questions/15843802/c-zoom-into-the-centre-of-the-screen-in-2d-coordinates

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!