| View previous topic :: View next topic |
| Author |
Message |
TonyV Site Admin

Joined: 07 Feb 2006 Posts: 1509 Location: Paragon City, Rhode Island
|
Posted: Thu Dec 28, 2006 9:29 am Post subject: FAQ: How to figure out where to put stuff on maps |
|
|
Overview
One of the things that I pride myself on is being accurate to a fault. Seriously. It's annoying. Yes, even to me. In this article, I will describe various methods that I've used to figure out where exactly things go on maps.
Coordinates
Unless you want to simply use trial-and-error (a legitimate method, which will be discussed shortly), you're going to have to first understand how coordinates work in City of Heroes.
I won't delve too deeply into this subject, because there's an article written specifically about it in the Wiki. I will mention, however, these key differences between image coordinates expressed in pixels and the in-game map coordinates given by the /loc command and recorded in demorecord files:
- The in-game map coordinates are in units of feet. So, for example, the coordinates (0, 0, 0) and (0, 0, 100) are 100 feet apart.
- The in-game map coordinates have three coordinates each. The first number is the x component (i.e. the east-west) component of the coordinates. The second number is the y component (i.e. the up-down) component of the coordinates. The third number is the z component (i.e. the north-south) component of the coordinates.
- The x-coordinate increases as one moves from right to left on a map (from east to west). This confuses a lot of people, but the coordinate (100, 0, 0), for example is 100 feet to the left (west) of the coordinate (0, 0, 0). The y-coordinate increases as one increases altitude. The z-coordinate increases as one moves from the top of the map to the bottom (from north to south).
- Coordinates can be, and indeed frequently are, negative. The origin of a map, that is, the coordinate (0, 0, 0), is not at any particular place. Sometimes, it's not even on the map at all.
- As a result of that last point, the top left edge of an in-game map is never (that I know of) a nice, round number.
- In-game map coordinates do not have to be integers. For most practical purposes, there's no such thing as 47.3 pixels, but there most certainly is such thing as 47.3 feet.
It's very helpful to become familiar with how coordinates work in the game, as they are used very frequently. For example, the Healing Node badge is located in Skyway City at coordinates (1577, -84, -677). If you run a /loc command and it tells you that you are at coordinates (-284.7, 0, -1284), how do you get to the badge? Well, to increase the first coordinate from -284.7 to 1577, you need to travel west (left). To decrease the second coordinate from 0 to -84, you need to descend. This usually involves climbing down some stairs, jumping from a landing down to street level, or even descending into a cave. To increase the third coordinate from -1284 to -677 (remember, if you increase a negative number, its absolute value gets smaller), you need to move towards the bottom (south) of the map.
Marking a Spot Using Trial and Error
If you are trying to figure out where on a map a certain spot should go, one option you may employ is simple trial-and-error. Place a spot on the map (as per the discussion in another FAQ posted here) where you think it more-or-less ought to go. Then go into the game and see if you got it right. Exit the game, make any necessary adjustments, and try again.
There are a few things you may do to make the process a little easier. One is to take an in-game screenshot of your map to use as a reference. Stand where you want the marker to be on your in-game map and take a screenshot of it with the user interface turned on. To do so, type the command /screenshotui 1 and press enter. (To turn it back off, type /screenshotui 0 and press enter.) It really helps if you expand your map window as large as it will go and zoom in as far as you can before taking the screenshot, so that you may have as much map detail as possible.
Next, open your favorite graphics editor (The Gimp, right?) and compare the area of the screenshot to the map image file, and estimate as best as you can where you think the object you are placing should go. Use the map editing procedure to save your map as a .texture file and place it in the correct directory, go inside the game, and test out the results. Within two or three iterations, you should be able to have a rather accurate result.
Note that when a map is zoomed in, the resolution of the in-game map can be much higher than the map image itself. It is not unusual for one map image pixel to be several pixels wide on the in-game map. In such a circumstance, an object you wish to place may fall close to the edge between two image map pixels, and it could be very difficult to decide which pixel should be the focus of the object. This is normal, but it is also mitigated by the fact that 1) not many people use the map expanded to its full size and zoomed as far in as it will go, and 2) even if the in-game map is off by a few pixels due to the difference in resolution, if you are accurate, the object you are marking is typically within a few feet (a step or two) of the center of your mark.
Most of the objects on the Paragon Maps overlay and maps were placed using the trial-and-error method.
Using Map Scales and Offsets
Marking a spot on a map might be fine for some purposes. If you only need to add one or two objects to a map, it can be a quick and dirty method of getting the job done. But if you want to add a bunch of things that you know the coordinates of at one time, or you want to programmatically figure out where stuff should go, you need more. You need to be able to cook with gas. Well friend, calculating map scales and offsets is the propane of map editing, and it's time to fire up the cartographical grill.
Calculating Map Scales
As you probably noticed if you've ever tried editing a map using the trial-and-error described above, one pixel on the image map typically covers a bit of land area in the game. If we want to be able to calculate where exactly stuff goes on an image map, we need to know exactly how much area; or more specifically, what the ratio of in-game feet to map image pixels is.
Let's say, for the sake of figuring out how all of this works, that you have a map image with two pixels that you know the exact location of in-game. Your map image might look something like this:
In that particular map image, (x1, y1) happens to be the point (53, 29) and (x2, y2) happens to be (417, 157). (Go ahead, copy and paste it into your favorite image editor and check. ) You can use the Pythagorean Theorem to find the distance between these two points. I hope you haven't forgotten your high school geometry!
The distance between the two points is approximately 385.849712 pixels (rounded to 6 decimal places).
Now let's say you edit your map images so that those points are highlighted on it. (I do this a lot; I call them reference dots, or ref dots for short.) Here's an example of what one looks like on my maps, specifically the Skyway City mayhem mission map, in this instance:
You go into the game, stand right smack in the middle of the pixel on the map in-game and use /loc to get your coordinates. You discover that in-game, (x1, y1) is located at (1135.2, -1437.6). (Notice that I've left the altitude coordinate out of the reading.) You then proceed to the second point and discover it's located at (-2623.0, -116.0). We can find the in-game distance between these two points just as we did above:
The in-game distance between the two points is approximately 3983.803936 feet (rounded to 6 decimal places).
So we can see that 3983.803936 feet in-game is equal to 385.849712 pixels in the map image. This gives us our map scale:
3983.803936 feet = 385.849712 pixels, or
10.324755 feet = 1 pixel
Congratulations, you now know the scale of the map!
What exactly does this map scale mean? Well, for one thing, you know that for every 10.324755 feet you move your character on the in-game map, you are moving him or her 1 pixel on the image map. If you imagine the game map zoomed waaaay in, it might looks something like this:
It also means that if you put a point on a map image, that point will effectively cover an area 10.324755 feet square on each side (or 106.600566 square feet, for those of you who don't have a calculator handy). Also, it means that 10.324755 is the resolution of the map; if two objects on the map are closer than 10.324755 feet apart vertically or horizontally, it may be impossible to show both of them using distinct points on the map.
This limitation sometimes shows up on map overlays. If you go to the exact center of a badge marker on a map, the marker may be, say, four or so feet away from you. Why is it not shown exactly lined up? Because if the marker on the map is placed one more pixel over, it's actually being moved 10.324755 feet, which would be further away than the four feet it is using the pixel the marker is on.
We can use what we've learned so far to create a generic formula for figuring out the scale of a map given two points that we know both in pixel coordinates and in in-game feet coordinates. It is:
(Distance in feet) / (Distance in pixels)
Or, expanding it out:
Where SF is the scale of the map, (xF1, yF1) and (xF2, yF2) are the in-game coordinates of the points in feet, and (xP1, yP1) and (xP2, yP2) are the coordinates of the points in the image map in pixels. Since the terms get squared and that makes negative numbers go away, it doesn't matter which point you specify as your first or second point.
Calculating Map Offsets
Now that we have the map scale, we're almost ready to start putting things on the map. However, there's one more thing that will come in handy: the map offsets.
Let's start out with a simple question using the example we've been working with.
We know that the in-game coordinates (1135.2, -1437.6), which I'm going to designate (1135.2, -1437.6)F for "feet", mark the center of the pixel in the image map at (53, 29), which I'm going to likewise designate (53, 29)P for "pixels".
We also know that the in-game coordinates (-2623.0, -116.0)F mark the center of the pixel in the image map at (417, 157)P.
The question is, in which pixel would we find the coordinates of, say, (-461.7, -314.4)F?
Well, to find out, we need to figure out how far, in pixels, the set of coordinates we're looking for is from a known point. We'll try the second point a little later, but for now, let's start out by using the first point.
Using any handy calculator, we can figure out that (-461.7, -314.4)F is 1596.9 feet east of, and 1123.2 feet south of, (1135.2, -1437.6)F. We also know that one pixel is 10.324755 feet. Using this information, we know that:
1596.9 feet * (1 pixel / 10.324755 feet) = 154.7 pixels
1123.2 feet * (1 pixel / 10.324755 feet) = 108.8 pixels
So the coordinates of interest are 154.7 pixels right (east) of, and 108.8 pixels below (south of), our original coordinates of (53, 29)P. That would put it at (207.7, 137.8)P. Since we can't have fractional pixels, we'll round it to (208, 138)P. The result is shown here:
Let's double-check our math by calculating where that point would be from the second point, (-2623.0, -116.0)F. We see that it is 2161.3 to the left (west) of, and 198.4 feet above (north of), the second point. Using our map scale, this translates to:
2161.3 feet * (1 pixel / 10.324755 feet) = 209.3 pixels
198.4 feet * (1 pixel / 10.324755 feet) = 19.2 pixels
So the coordinates of interest are 209.3 pixels left (west) of, and 19.2 pixels above (north of), our original coordinates of (417, 157)P. That would put it at (207.7, 137.8)P. Again we round, and we end up with (208, 138)P. Notice that this result is identical to the one above.
Once you have the map scale and any given point's in-game coordinates and map image coordinates, you can calculate any other given point's coordinates relative to that point. But you know what would be really handy? If we could come up with some sort of formula that doesn't depend on just any arbitrary point. Let's pick one that actually has some kind of significance. How about the top left corner of the map? In other words, let's calculate the in-game coordinates of (0, 0)P, and we can use that to calculate all other coordinates.
We know that the point (1135.2, -1437.6)F is 53 pixels right of, and 29 pixels below, (0, 0)P because it's coordinates are, well, (53, 29)P. We also know that each pixel is 10.324755 feet. This allows us to calculate:
53 pixels * (10.324755 feet / pixel) = 547.212015 feet
29 pixels * (10.324755 feet / pixel) = 299.417895 feet
So (0, 0)P is 547.212015 feet to the left (west) of, and 299.417895 feet above (north of) the point (1135.2, -1437.6)F. Remembering that x-coordinates grow as you move left on an in-game map, and that y-coordinates shrink as you move up, we can calculate:
(0, 0)P = (1135.2 + 547.212015, -1437.6 - 299.417895)F = (1682.412015, -1737.017895)F
Well, lookey there, now we have something and can save ourselves some trouble! Given that (0, 0)P = (1682.412015, -1737.017895)F, let's calculate once again where (-461.7, -314.4)F is.
We know that -461.7F is 2144.112015 feet to the right of (0, 0)P because that's how far it is from 1682.412015F. Likewise, we know that -314.4F is 1422.617895 feet below (0, 0)P. Let's see what that is in pixels:
2144.112015 feet * (1 pixel / 10.324755 feet) = 207.7 pixels
1422.617895 feet * (1 pixel / 10.324755 feet) = 137.8 pixels
Rounding, we have 208 pixels right of (0, 0)P and 138 pixels below (0, 0)P. Since we're calculating all of this from (0, 0)P, we don't have to add or subtract anything else. The location is simply (208, 138)P.
See? I told you it was handy!
Putting It All Together
Now, let's come up with a formula for finding a set of image map coordinates given any set of in-game coordinates. As we figured out above, the scale of any map, given the in-game coordinates and image map coordinates of any two points, is:
From there, we'll use either of the points to figure out where (0, 0)P is on the map:
Remember, to go towards the left edge of the map, we have to add to the x-coordinate. To go towards the top edge of the map, we have to subtract from the y-coordinate. Don't look at me, I didn't make that up, and they didn't call and ask my opinion on the matter when they wrote the code that runs the game.
So now that we have the scale of the map and the in-game coordinates of the top left corner, we can put together a general formula. Here it is:
Typically, you'll use those last three equations just as I've presented them. First, you'll calculate a scale for a map. Next, you'll calculate the in-game coordinates for the top left corner of the map. Last, but not least, once you have those two items, you'll start tossing in in-game coordinates and churning out map image coordinates that you'll use to do things like place items on a custom map that you're developing.
A Note About Rounding
I kind of casually glossed over how the coordinates are rounded. For most practical purposes, everything I've said so far will work perfectly fine. If you're a stickler like me, though, you may have noticed that we've been assuming the whole time that the known in-game coordinates are smack dab in the middle of a map image pixel. You might wonder, "How will that affect my calculations?" I know I did. And if you know about this stuff now, it will make life easier if you decide you want to start doing things like cropping or scaling you image maps. (For example, to pan or zoom around on a map on a web site.)
When we converted our in-game coordinates to map image coordinates, we mapped our points of interest into the middle of a pixel. For example, we said that (0, 0)P is at (1682.412015, -1737.017895)F. Technically, (1682.412015, -1737.017895)F is the center of (0, 0)P. The area covered by (0, 0)P is actually a chunk of land that stretches from approximately 1687.574393F to 1677.249638F horizontally, and -1742.180273F to -1731.855518F vertically. In other words, it looks something like this:
When you convert coordinates using the equations above, notice that you're essentially mapping all coordinates into the center of their associated pixels. If we break it down into "fractional" pixels, though, notice how it looks:
This is why rounding works. Any pixel calculation that ends up, for example, between 3.5 and infinitesimally close to 4.5, inclusive, will be located at 4P, which is exactly what you would get if you rounded the value.
I'll dig more into rounding when some of the more advanced topics are discussed. In the meantime, it will suffice just to say that you should keep in mind that, as mentioned, the coordinate conversion equations are based on measurements made from the middle of pixels.
Where To From Here?
Another thing I've glossed over is how exactly you figure out what the coordinates of the middle of a pixel is. You can, of course, just eyeball it on your game map and use /loc to get your coordinates, and this will give you a reasonable degree of accuracy. However, those tenths of a foot can add up, causing some of the plotted points to be off by a pixel now and then.
There are ways of getting much, much more accurate readings, down to within thousandths of an in-game inch! In the next article, I'll discuss some of the methods I use for getting what I believe are the most accurate measurements of map scales and offsets.
Last edited by TonyV on Sun May 20, 2007 7:17 am; edited 2 times in total |
|
| Back to top |
|
 |
TonyV Site Admin

Joined: 07 Feb 2006 Posts: 1509 Location: Paragon City, Rhode Island
|
Posted: Thu Dec 28, 2006 3:45 pm Post subject: |
|
|
Just for fun, I threw together a little javascript app that will use the exactly process above to show you what the map scale and offsets are given the x and y coordinates, in map image pixels and in-game feet, of any two points on a map. Here's the link, enjoy!
If you fill in the numbers from the example above, it will actually be a little off. When I was working the calculation above, I rounded everything off to six decimal places. The little utility page does, too, but it actually keeps the more accurate numbers for calculations further down the line. In reality, any application you write should probably keep as much accuracy as it can. At some point in the future, I'll discuss how to calculate the error you're causing by rounding. (Which there will always be some; even the game rounds everything to six decimal places internally.) That way you can figure out stuff like a percentage that represents how accurate your maps are.
Here's what it will look like with the example above:
 |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|