The project I am working on is very simple. It's just a raycaster similar to the one used in Wolfenstein 3D. I'm using just the standard Win32 graphics capabilities (not GDI, see below). However, I'm running into issues with directional programming and math given that my screen coordinate system uses top-left as the origin. As such, x increases when going right to left (like usual), but y increases going top to bottom. Therefore, considering all the functions required for movement and rotation using a raycaster, the unit circle for my raycaster looks like:
180
|
270---|---90
|
0
It's not that the coordinate system is rotated, it's that it's flipped over the Y axis. One obvious issue (among many others I'm sure) is that if you attempt to rotate clockwise, your direction angle DECREASES in degrees, so you actually rotate counterclockwise.
I struggle with simple math enough as it is, so even a standard coordinate system with 0 pointing “up” would be challenging enough for me, but this just throws in a cruel twist.
Most graphics systems seem to use top-left origin, and I'm sure there has been more than 1 person out there who wanted to goof around with building a raycaster, so I imagine this problem has been discussed quite a bit. I've found a few articles online, but maybe I'm just not searching with the correct terms because I don't come up with much.
It seems that there are 3 basic solutions:
- Change the graphics system to use bottom-left as the origin. This is something I could do. My graphics “system” (strong word) is basically just drawing to the memory of an offscreen bitmap, then blitting the bitmap to the Win32 window. I have control over whether my system is top-left or bottom-left. But if you were using a graphics library where the origin was fixed at top-left, this wouldn't be an option.
- Convert the player attributes (xPos, yPos, direction, etc) from top-left to bottom-left coordinates at the beginning of the game loop after updating position but before running all the trigonometry. It would seem that you would basically need two sets of variables, e.g. xPos, yPos, and dir, PLUS xPosCorrected, yPosCorrected, dirCorrected. The first 3 store the information on your player based on the top-left coordinate system being used. So if you move your player “down”, the yPos will become larger, if you rotate clockwise, your player angle will decrease, etc. Then, convert these variables to a bottom-left coordinate system. So if your screen height is 100, and your player is at yPos = 80, you convert that to yPosCorrected = 20. And for the direction, you take the y-component and make it negative to flip it back over the y-axis and store it in dirCorrected. And then when you do your math, you use xPosCorrected, yPosCorrected, and dirCorrected instead.
- You just live with the messed up unit circle situation. For example, if your player presses the rotate clockwise button, you subtract from the angle. Even though that is counterintuitive. But, are there other issues besides a simple rotation problem that would come up eventually?
Like with everything, I'm sure there are hidden problems with some or all of these that may not be immediately apparent. But I just wanted some advice on different ways to handle this issue. I would prefer to design it the best way from the start rather than have to switch gears midstream.