views:

101

answers:

2

Hi there! It might be that my math is rusty or I'm just stuck in my box after trying to solve this for so long, either way I need your help.

Background: I'm making a 2d-based game in C# using XNA. In that game I want a camera to be able to zoom in/out so that a certain part of objects always are in view. Needless to say, the objects move in two dimensions while the camera moves in three.

Situation: I'm currently using basic trigonometry to calculate which height the camera should be at for all objects to show. I also position the camera between those objects.

It looks something like this:

1.Loop through all objects to find the outer edges of our objects : farRight, farLeft, farUp, farDown.

2.When we know what the edges of what has to be shown are, calculate the center, also known as the camera position:

CenterX = farLeft + (farRight - farLeft) * 0.5f;
CenterY = farUp + (farDown - farUp) * 0.5f;

3.Loop through our edges to find the largest value compared to our camera position, thus the furthest distance from the center of screen.

4.Using the largest distance-value we can easily calculate the needed height to show all of those objects (points):

float T = 90f - Constants.CAMERA_FIELDOFVIEW * 0.5f;
float height = (float)Math.Tan(MathHelper.ToRadians(T)) * (length);

So far so good, the camera positions itself perfectly based on the calculations.

Problem:

a) My rendering target is 1280*720 with a Field of View of 45 degrees, so one always sees a bit more on the X-axis, 560 pixels more actually. This is not a problem per se but more one that on b)...

b) I want the camera to be a bit further out than it is, so that one sees a bit more on what is happening beyond the furthest point. Sure, this happens on the X-axis, but that is technically my flawed logic's result. I want to be able to see more on both the X- and Y-axis and to control this behavior.

Question

Uhm, so to clarify. I would like to have some input on a way to make the camera position itself, creating this state:

Objects won't get closer than say... 150 pixels to the edge of the X-axis and 100 pixels to the edge of the Y-axis. To do this the camera shall position itself along the Z-axis so that the field of view covers it all.

I don't need help with the coding, just the math and logic of calculating the height of my camera. As you probably can see, I have a hard time wrapping this inside my head and even harder time trying to explain it to you.

If anyone out there has been dealing with this or is just better than me at math, I'd appreciate whatever you have to say! :)

+2  A: 

Don't you just need to add or subtract 150 or 100 pixels (depending on which edge you are looking at) to each distance measurement in your loop at step 3 and carry this larger value into length at step 4? Or am I missing something.

Andrew Walker
+1 simple and sounds right. Another option would be to add a fudge factor to the final result, height.
Azim
Adding height: Was my first idea, but I soon realized that my problem with the X-axis was still there.Adding/subtracting from points: Well, this is my best bet right now it seems. However without this my objects stayed in the same place in screen space. Now they tend to "gravitate" from the screen's edge. Ah well, this method performs reasonably well.
Robelirobban
You'll need to add to the height (when thinking about the Z-axis edges) and the width in (when thinking about the X axis) your loop over all objects to find the length.
Andrew Walker
A: 

I can't explore this area further at the moment, but if anyone is having the same issue but is not satisfied by provided answer there is another possibility in XNA.

ViewPort.Unproject()

This nifty feature converts a screen space coordinate to a world space one.

ViewPort.Project()

Does the opposite thing, namely converting world space to screen space. Just thought that someone might want to go further than me. As much as my OCD hates to leave things not perfect, I can't be perfectioning this... yet.

Robelirobban