Created
June 6, 2013 00:26
-
-
Save gszauer/5718413 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The simplest method of projecting a 3D point onto a 3D screen assumes that we are in the camera coordinate system; that is all points are specified in relation to the viewer, who is assumed to be at (0, 0, 0). Assuming that the coordinates of the center of the display are at (0, 0), +X is right and +y is up: | |
screen_x = vector.x / vector.z; | |
screen_y = vector.y / vector.z; | |
In the vga (0, 0) is top left and +Y is going down; Lets account for the skewed center and inverted y: | |
screen_x = vector.x / vector.z + HALF_SCREEN_WIDTH; | |
screen_y = -1.0 * vector.y / vector.z + HALF_SCREEN_HEIGHT; | |
While correct, the above code will greatly exaggerate the effects of of perspective. To somewhat offset this a fixed multiplier should be applied: | |
screen_x = vector.x * perspective_compensate / vector.z + HALF_SCREEN_WIDTH | |
screen_y = -1.0 * vector.y * perspective_compensate / vector.z + HALF_SCREEN_HEIGHT | |
The key to understanding the perspective_compensate is understanding field of view. | |
tan(hfov / 2) = HALF_SCREEN_WIDTH / distance_to_monitor | |
tan(vfov / 2) = HALF_SCREEN_HEIGHT / distance_to_monitor | |
horizontal_perspective_compensate = HALF_SCREEN_WIDTH / tan(horizontal_fov / 2) | |
vertical_perspective_compensate = HALF_SCREEN_HEIGHT / tan(vertical_fov / 2) | |
Lets plug in some numbers | |
horizontal_perspective_compensate = (320 / 2) / tan(60 / 2) | |
160 / tan(30) | |
~277 | |
60 degrees is ideal for both horizontal and vertical field of view | |
This is a pretty good solution, however we are still left with the problem of using a correct aspect ratio | |
aspect_ration = vertical_resolution / horizontal_resolution | |
With aspect correction the final projected coordinates are | |
screen_x = vector.x * horizontal_perspective_correct / vector.z + HALF_SCREEN_WIDTH | |
screen_y = -1.0 * vector.y * vertical_perspective_correct / vector.z + HALF_SCREEN_HEIGHT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment