2
$\begingroup$

I am using a small microcontroller, which has limited processing resources. I need to calculate the three tangents:

tan(theta) tan(hdg + theta) tan(90 - hdg + theta) 

theta is virtually constant (it is a field of view); hdg may change. tan(theta) is provided by doing sin(theta)/cos(theta) (in my library), so that all tangents in total incur six trig function calls... which slows it down a lot.

Is it possible to calculate all of these at once?

  • 1
    Depending on the resolution/accuracy required, you can calculate a table at start time and store it, then interpolate to avoid all run time trig. I had an application where storing every 5 degrees was su$f$$f$icient (only 19 lines) and even inter$p$olation wasn't needed. Very fast then.2011-05-11

2 Answers 2

6

Well, there are addition formulas for $\tan$:

$\begin{align} \tan (v + u) = \frac{\tan v + \tan u}{1 - \tan v \tan u} \\ \tan (v - u) = \frac{\tan v - \tan u}{1 + \tan v \tan u} \end{align}$

So you can compute $\tan(hdg)$ and $\tan(\theta)$ then plug them into the first formula to get $\tan(\theta+hdg)$.

For the other formula you get have $\tan (90^\circ - w) = \cot w = \frac{1}{\tan w}$ where $w = hdg - \theta$, i.e.

$\tan (90^\circ - (hdg - \theta)) = \frac{1}{\tan (hdg-\theta)} = \frac{1}{\frac{\tan hdg - \tan \theta}{1+\tan hdg \tan \theta}} = \frac{1 + \tan hdg \tan \theta}{\tan hdg - \tan \theta}$

so you can once again use your previously calculated values for $\tan \theta$ and $\tan hdg$.

You might want to look into another way of evaulating $\tan x$. If your angle $x$ is smaller than $22.5^\circ$ you can use the polynomial

$\tan x \approx x + \frac{x^3}{3} + \frac{2x^5}{15} + \frac{17x^7}{315}$

Note that this is for an angle in radians, so you have to convert your angle from degrees to radians by multiplying by $\frac{\pi}{180} \approx 0.0174533$ You probably want to evaulate this using Horner's rule. Depending on how sensitive things are you might be able to drop one (or two) terms.

If your angle is larger than $22.5^\circ$ (or what limit you find suitable), you can use the half angle formula $\tan x = \frac{2 \tan \frac{x}{2}}{1-\tan^2 \frac{x}{2}}$ or the reciprocal $\tan x = \frac{1}{\tan (90^\circ - x)}$ depending on how large your angle is.

I don't know if this will be quicker or not, but it might be worth a shot.

  • 0
    If more accurate Padé approximants are needed, one way to obtain them is by appropriately truncating the [continued fraction for the tangent](http://functions.wolfram.com/ElementaryFunctions/Tan/10/0001/).2011-05-11
3

If hdg changes by constant increments, you might want to implement the following formulae (found in Numerical Recipes)

$\cos(\theta+\delta) = \cos\theta-(\alpha\cos\theta+\beta\sin\theta)$

$\sin(\theta+\delta) = \sin\theta-(\alpha\sin\theta-\beta\cos\theta)$

$\alpha=2\sin^2\frac\delta2,\qquad\beta=\sin\delta$

The brackets indicate in which order the operations should be performed in order to minimize floating-point errors.

  • 2
    I note that these stable recursions are easily derived from the complex exponential form. Resist the urge to "simplify" $2\sin^2\frac\delta2$ to $1-\cos\delta$; the reason for using the former instead of the latter is that you avoid the subtractive cancellation inherent in computing $1-\cos\delta$ for "tiny" $\delta$ (hint: Maclaurin).2011-05-11