Developers Web home

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

No conversation on this topic You must be logged in to add to the conversation