PanGazer – gnomonic projection When viewing an image spherically, PanGazer uses the gnomonic projection (also known as the rectilinear or equirectangular projection) to map the spherical coordinates of the image to the rectangular coordinates of the view window on-screen.  This projection effectively places the view window as though it touches (is tangent to) the sphere of the image, and has the advantage that it maps great circles in the spherical image to straight lines in the projected view.  In particular, the horizon in a spherical panorama is always shown as a horizontal line. Note that angles of view of a spherical image projected this way are therefore slightly smaller than those calculated for a ‘flat’ image because the projection plane is further away from the viewpoint. The gnomonic projection The transformation used in PanGazer is the inverse gnomonic projection described at Wolfram MathWorld », and mathematically can be written: latitude   φ = sin−1(cos c sin φ1 + (y sin c cos φ1)/ρ) longitude λ = λ0 + tan−1( (x sin c) / (ρ cos φ1 cos c − y sin φ1 sin c) ) where x and y are the coordinates of a point in the view image (e.g., in the range ±1 for an angle of view of 90°) φ1 is the pitch of the viewpoint (in range ±π/2) λ0 is the yaw of the viewpoint (in range ±π) ρ = √(x² + y²) c = tan−1 ρ   Improving the performance of the projection At first glance, for each point in the image the formulae for φ and λ require 12 calls to trigonometric functions along with a square root, two divisions, and 15 multiplies or additions. A full-screen view on a medium-sized monitor (2560 × 1440) has nearly four million points, so when dragging the view at a frame rate of 25 frames/second each point has to be calculated in about 10ns, which is less than the typical cost of a single trigonometric function on a 2.5GHz processor.  A naïve implementation of these formulae is therefore too slow for implementation on a general-purpose processor, even if the work is spread over several cores.   However, there are a number of simplifications that can be applied which considerably reduce the cost: φ1 is a constant for any given rendering, so sinphi1 = sin φ1 and cosphi1 = cos φ1 can be pre-calculated a more interesting observation is that (using the known trigonometic identity ») cosc = cos c is given by cos(tan−1 ρ) which is 1/√(1 + ρ²); this is usually very much faster because the square root function is routinely a hardware instruction that is as fast as a division. similarly, sinc = sin c is given by sin(tan−1 ρ) which is ρ/√(1 + ρ²) – which is simply ρ cosc. In the formula for φ, sinc/ρ can be replaced by cosc, giving: φ = sin−1( (sinphi1 + y cosphi1) cosc) and in the formula for λ the numerator and denominator of the division can be divided by sinc and then cosc/sinc is 1/ρ, so the formula simplifies to: λ = λ0 + tan−1(x / (cosphi1 − y sinphi1) ) (note that sinc therefore does not need to be calculated, and both the ρ terms in the formulae cancel so ρ itself need not be calculated, only ρ²). Therefore, assuming that cosphi1 and sinphi1 are pre-calculated, the computation costs are: a square root (usually a hardware instruction), two additions, and two or three multiplications (one does not need to be calculated for every point) and an inversion to calculate cosc one trigonometric function, one addition, and two multiplications to calculate φ one trigonometric function, two additions, a multiplication, and a divide to calculate λ. In practice, the atan2 function can be used in many programming languages to avoid the division in the calculation of λ, and lookup tables can be used for the trigonometric functions if the accuracy requirements are not too high, giving further speed improvements. In summary, the simplified formulae require calls to two trigonometric functions along with a square root, at most one division, and fewer than 12 multiplies or additions.  The result is a fast gnomonic projection algorithm.  In PanGazer, performance is further improved by multi-threaded drawing so that all the cores of the processor are used.