\documentclass[letterpaper,10pt]{article} \usepackage{amsmath} \usepackage[empty,cm]{fullpage} \pagenumbering{gobble} \begin{document} \title{Pannellum Equirectangular Projection Reference} \author{Matthew Petroff} \date{January 2013} \maketitle Let a coordinate system be defined with the origin at the focal point, the x-axis parallel to the camera's horizontal axis with positive to the right as viewed from behind the camera, the y-axis parallel to the camera's vertical axis with positive upward as viewed from behind the camera, and the z-axis be perpendicular to these two axes with positive extending away from the camera.\footnote{Note that this is a left-handed coordinate system.} Let \(\lambda\) represent the panorama's longitude, \(\phi\) the panorama's latitude, \(\theta\) the latitudinal offset, \(\psi\) the longitudinal offset, and \(f\) the focal length. Let \(\mathbf{a}\) represent a point's position vector, \(\mathrm{R}_x(\theta)\) the latitudinal rotation matrix, \(\mathbf{d}\) a point's position vector in the camera's reference frame, \(x\) and \(y\) a point's position on the image plane, and \(p_x\) and \(p_y\) a point's position on an equirectangular projection. \begin{equation} \label{eq:posvec} \mathbf{a} = \begin{bmatrix} \mathbf{a}_x \\ \mathbf{a}_y \\ \mathbf{a}_z \end{bmatrix} = \begin{bmatrix} \sin(\lambda)\cos(\phi) \\ \sin(\phi) \\ \cos(\phi)\cos(\lambda) \end{bmatrix} \end{equation} \begin{equation} \label{eq:rotmat} \mathrm{R}_x(\theta) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos(\theta) & -\sin(\theta) \\ 0 & \sin(\theta) & \cos(\theta) \end{bmatrix} \end{equation} With a point's position vector \eqref{eq:posvec} and the latitudinal rotation matrix \eqref{eq:rotmat}, one can calculate a point's position in the camera's reference frame.\nopagebreak \begin{equation} \mathbf{d} = \begin{bmatrix} \mathbf{d}_x \\ \mathbf{d}_y \\ \mathbf{d}_z \end{bmatrix} = \mathrm{R}_x(\theta)\mathbf{a} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos(\theta) & -\sin(\theta) \\ 0 & \sin(\theta) & \cos(\theta) \end{bmatrix} \begin{bmatrix} \sin(\lambda)\cos(\phi) \\ \sin(\phi) \\ \cos(\phi)\cos(\lambda) \end{bmatrix} = \begin{bmatrix} \sin(\lambda)\cos(\phi) \\ \sin(\phi)\cos(\theta) - \cos(\phi)\cos(\lambda)\sin(\theta) \\ \sin(\phi)\sin(\theta) + \cos(\phi)\cos(\lambda)\cos(\theta) \end{bmatrix} \end{equation} Using the pinhole camera model, one can then calculate positions on the image plane.\nopagebreak \begin{equation} \begin{bmatrix} x \\ y \end{bmatrix} = \frac{f}{\mathbf{d}_z} \begin{bmatrix} \mathbf{d}_x \\ \mathbf{d}_y \end{bmatrix} = \frac{f}{\sin(\phi)\sin(\theta) + \cos(\phi)\cos(\lambda)\cos(\theta)} \begin{bmatrix} \sin(\lambda)\cos(\phi) \\ \sin(\phi)\cos(\theta) - \cos(\phi)\cos(\lambda)\sin(\theta) \end{bmatrix} \end{equation} \begin{equation} \label{eq:xf} \frac{x}{f} = \frac{\sin(\lambda)\cos(\phi)}{\sin(\phi)\sin(\theta) + \cos(\phi)\cos(\lambda)\cos(\theta)} \end{equation} \begin{equation} \label{eq:yf} \frac{y}{f} = \frac{\sin(\phi)\cos(\theta) - \cos(\phi)\cos(\lambda)\sin(\theta)}{\sin(\phi)\sin(\theta) + \cos(\phi)\cos(\lambda)\cos(\theta)} \end{equation} Solving the system of \eqref{eq:xf} and \eqref{eq:yf} for \(\lambda\) and \(\phi\) and adding the longitudinal offset, one is able to find a point's position on the unit sphere from its position on the image plane.\nopagebreak \begin{equation} \lambda = \tan ^{-1}\left(\frac{x}{\sqrt{x^2 + \left(f \cos(\theta) - y \sin(\theta) \right)^2}},\frac{f \cos(\theta) - y \sin(\theta)}{\sqrt{x^2 + \left(f \cos(\theta) - y \sin(\theta) \right)^2}}\right) + \psi \end{equation} \begin{equation} \phi = \tan ^{-1}\left(\frac{y \cos(\theta) + f \sin(\theta)}{\sqrt{x^2 + \left(f \cos(\theta) - y \sin(\theta) \right)^2}}\right) \end{equation} Once a point's position on the unit sphere is known, it is trivial to find its position on an equirectangular projection.\nopagebreak \begin{equation} p_x = \frac{\lambda}{\pi} \end{equation} \begin{equation} p_y = \frac{\phi}{\frac{\pi}{2}} \end{equation} \end{document}