# Difficulties with zoom point

I want to zoom about an arbitrary zoom point. For example, if the player tabs on a place on his windows phone display, this place(position) should get the new center of his viewport. In addition, the camera zooms so that the place looks bigger. If the player tabs again in zoom mode, the camera just needs to zoom out and the center of the viewport rests the same like in zoom mode.

I'm doing a 2D point and click adventure, so it is very important to examine the environment.

If I tab on a place, it's not getting the center of the viewport. The center of the viewport always is somewhere else. What is wrong with my code?

I found the camera class in this tutorial: http://www.david-amador.com/2009/10/xna-camera-2d-with-zoom-and-rotation/

How can I do the zoom? I found a similar question on stackoverflow but I don't understand how they solved the problem: http://stackoverflow.com/questions/9348866/xna-2d-camera-with-arbitrary-zoom-center

Camera class:

``````public class Camera2d
{
protected float _zoom; // Camera Zoom
public Matrix _transform; // Matrix Transform
public Vector2 _pos; // Camera Position
protected float _rotation; // Camera Rotation

public Camera2d()
{
_zoom = 1.0f;
_rotation = 0.0f;
_pos = Vector2.Zero;
}

// Sets and gets zoom
public float Zoom
{
get { return _zoom; }
set { _zoom = value; if (_zoom < 0.1f) _zoom = 0.1f; } // Negative zoom will flip image
}

public float Rotation
{
get { return _rotation; }
set { _rotation = value; }
}

// Auxiliary function to move the camera
public void Move(Vector2 amount)
{
_pos += amount;
}
// Get set position
public Vector2 Pos
{
get { return _pos; }
set { _pos = value; }
}

public Matrix get_transformation(GraphicsDevice graphicsDevice)
{
Viewport viewPort = graphicsDevice.Viewport;
_transform =
Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(viewPort.Width * 0.5f, viewPort.Height * 0.5f, 0));
return _transform;
}
}
``````

How I use the camera:

``````GestureSample gs;
cam.Pos = new Vector2(graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight / 2);
TouchPanel.EnabledGestures = GestureType.Tap;

void UpdateZoom(float newZoom)
{
Vector2 currentMouseTarget = new Vector2(cam.Zoom * gs.Position.X, cam.Zoom * gs.Position.Y);
Vector2 nextMouseTarget = new Vector2(newZoom * gs.Position.X, newZoom * gs.Position.Y);
cam.Pos += (nextMouseTarget - currentMouseTarget) * newZoom;
cam.Zoom = newZoom;
}

protected override void Update(GameTime gameTime)
{
while (TouchPanel.IsGestureAvailable)
{
switch (gs.GestureType)
{
case GestureType.Tap:
UpdateZoom(2.0f);
break;
}
}

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null,
null,
null,
null,
cam.get_transformation(graphics.GraphicsDevice));

spriteBatch.Draw(TestSprite, new Rectangle(200, 200, TestSprite.Width,TestSprite.Height), null,Color.White,0,new Vector2(TestSprite.Width/2,TestSprite.Height/2), SpriteEffects.None,1);

spriteBatch.End();

base.Draw(gameTime);
}
``````
-
Typically "What is wrong with my code" questions are frowned upon. They're usually only beneficial to the one individual asking the question, since they're likely the only ones using that exact code. You may want to rephrase the question to ask about strategies for doing this, or explain where you think the problem is, what you've tried and how it hasn't worked. – Byte56 Aug 6 '13 at 23:34

You should calculate the target position with the previous zoom, and calculate it again with the new zoom, and then add the difference to the camera position.

Should be something similar to this (not tested):

`````` void UpdateZoom(float newZoom) {
currentMouseTarget = Zoom * MousePos;
nextMouseTarget = newZoom *  MousePos;

CameraPos += (nextMouseTarget - currentMouseTarget) (/ or *) newZoom;

Zoom = newZoom;
}
``````

EDIT:

If you want to zoom about a certain point (target) and translate camera to the meet center of viewport... your code should similar to this:

``````  Camera.Position += ( Target.Position * Camera.Zoom - Camera.Position ) * 0.1f;
``````

This way it will interpolate with easing to move the camera to the target.Position

-
Why are you writing (/ or *)? – Bryan Aug 7 '13 at 5:43
Because I was not sure ... have you tested it? – Blau Aug 7 '13 at 6:43
I tried it with / and *, but it's not working. If I tab on a place, the place isn't getting the center of the viewport. I updated my question with the new code. In addition, I found a similar question on stackoverflow but I don't understand how they solved the problem. – Bryan Aug 7 '13 at 15:33
I understood that you want to zoom about a point... not translate that point to the center – Blau Aug 7 '13 at 16:25