C ++ Zoom au centre de l’écran en coordonnées 2D

Je ne parviens pas à faire les calculs corrects pour zoomer au centre de l’écran en coordonnées 2D tout en conservant le bon réglage.

J’ai un vecteur que j’utilise pour gérer les déplacements dans l’éditeur de carte, comme suit:

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

Il est réglé sur -640.0f, -360.0f pour que 0,0 soit le centre de l’écran lors de l’initialisation (ma fenêtre étant 1280×720).

Ma valeur de zoom est comprise entre 0,1f et 2,0f et augmente ou diminue par incréments de 0,05:

 zoomScale = zoomScale + 0.05; 

Lorsque vous dessinez des éléments à l’écran, ils sont dessinés à l’aide du code suivant:

 sf::Rect 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 est une valeur utilisée pour redimensionner des couches de segments pour le défilement de parallaxe.

Cela semble fonctionner correctement pour les zooms avant et arrière, mais le point central semble se déplacer (un élément que je sais qu’il devrait toujours être à 0,0 sera situé à des coordonnées différentes dès que je ferai un zoom). J’utilise ce qui suit pour calculer quelle est la position de la souris pour tester ceci de la manière suivante:

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

Je suis sûr qu’il y a un calcul que je devrais faire avec le vecteur ‘scroll’ pour prendre en compte ce zoom mais je n’arrive pas à le faire fonctionner correctement.

J’ai essayé d’implémenter quelque chose comme ci-dessous mais cela n’a pas donné les bons résultats:

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

Des idées que je fais mal?

Je vais le faire facilement (pas très efficace, mais cela fonctionne bien) et uniquement pour un seul axe (le deuxième est identique)

il vaut mieux avoir offset non calibré:

 scaledpos = (unscaledpos*zoomscale)+scrolloffset 

connaître le point central ne doit pas bouger après le changement d’échelle (0 signifie avant 1 signifie après):

 scaledpos0 == scaledpos1 

alors faites ceci:

 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 

lorsque vous ne pouvez pas modifier l’équation de mise à l’échelle, faites de même avec le vôtre

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

J’espère que je n’ai pas commis d’erreur stupide (écrire de mémoire). Pour plus d’informations, voir

  • Zoom sur les graphiques en fonction de la position actuelle de la souris