Find the 2D point on a screen that would represent a point in 3D space
Translate a point in 3D space to a point on a 2D screen. As a concept, we are going to imagine what our eye would see, by translating the 3-dimensional point in space to a 2-dimensional polar position relative to the centre of vision. To make this calculation, we must first define our environment, with the following variables:  | [fromeye] - the distance between the observer/eye and the origin of the 3D space, where both lie on the y-axis [fov] - the field of view, defined as an angle in radians [onscreen] - the pixel radius the screen will use to define the [fov] | The point in 3D space is to be defined as P, with a position vecter of [Px,Py,Pz] Firstly, we must calculate the radial vector of the point P, relative to the y-aixs:  | ry - the polar radius α - the polar direction/angle ry = √( Px2 × Pz2 ) α = tan-1( Px / Pz ) | This gives the polar rotation α and polar radius. We must now calculate the proportion of the [fov] angle that this radius makes with the line of sight (y-axis).  | β = tan-1( ry / ( Py × [fromeye] ) ) | β must now be compared with [fov] and [onscreen] to derived the actual on-screen pixel radius of the point. To do this, we must calculate what the radius is with angles [fov] and β, at a distance of [fromeye] in the 3D space.  | R = [fromeye] × tan( [fov] ) r = [fromeye] × tan( β ) | Now the onscreen polar radius can be calculated, because the ratio r/R gives the proportion of the on-screen radius:  | polar radius Rp = [onscreen] × r / R Next we can calculate the on-screen 2D position in terms of x and y: x = Rp × sin( α ) y = Rp × cos( α ) | ∴ α = tan-1( Px / Pz ) ry = √( Px2 × Pz2 ) β = tan-1( ry / ( Py × [fromeye] ) ) R = [fromeye] × tan( [fov] ) r = [fromeye] × tan( β ) Rp = [onscreen] × r / R x = Rp × sin( α ) y = Rp × cos( α ) Which can be reduced to: x = [onscreen] × ( [fromeye] × tan( tan-1( √( Px2 × Pz2 ) / ( Py × [fromeye] ) ) ) ) / ( [fromeye] × tan( [fov] ) ) × sin( tan-1( Px / Pz ) ) y = [onscreen] × ( [fromeye] × tan( tan-1( √( Px2 × Pz2 ) / ( Py × [fromeye] ) ) ) ) / ( [fromeye] × tan( [fov] ) ) × cos( tan-1( Px / Pz ) ) which looks complicated, but when implemented into your code, does somehow look quite elegant. For the purpose of further calculations when building your 3D engine, the distance of Point P from the eye is also useful.  | d = √( ry2 + ( [fromeye] + Py )2 ) | As ry = √( Px2 × Pz2 ) now d = √( ( Px2 × Pz2 ) + ( [fromeye] + Py )2 ) d is the length through 3D space of the vector from eye to Point P
|