arctan
Show how to culculate arctan
1. By Taylor Series
Accurate but a bit slow to use in embedded system
arctan.js
let arctan = (x, taylorSeriesSize = 10) => {
const pow = (x, n) => {
if (n === 0) return 1;
if (n === 1) return x;
if (n % 2 === 0) {
return pow(x * x, n / 2);
} else {
return x * pow(x * x, (n - 1) / 2);
}
};
const n2n1 = (n) => 2 * n + 1;
const x2n1 = (n) => pow(x, n2n1(n));
const minus1n = (n) => (n % 2 === 0 ? 1 : -1);
const sigma = (n, xk) => [...Array(taylorSeriesSize).keys()].map(xk).reduce((xk0, xk1) => xk0 + xk1);
const pi = Math.PI;
let tan_rad;
if (x >= 1) {
tan_rad = pi / 2 - sigma(taylorSeriesSize, (n) => minus1n(n) / (n2n1(n) * x2n1(n)));
} else if (x <= -1) {
tan_rad = -pi / 2 - sigma(taylorSeriesSize, (n) => minus1n(n) / (n2n1(n) * x2n1(n)));
} else {
tan_rad = sigma(taylorSeriesSize, (n) => (minus1n(n) * x2n1(n)) / n2n1(n));
}
return (tan_rad / pi) * 180;
};
2. Suggested in Stack Overflow
Fast but inaccurate (e.g. arctan2(1.732) outputs 51°)
.js
let arctan2 = (x) => {
const pi = Math.PI;
const abs = Math.abs;
const rad = (pi / 4) * x - x * (abs(x) - 1) * (0.2447 + 0.0663 * abs(x));
return (rad / pi) * 180;
};
Comparision
Compare required time in milliseconds
.js
let time = (fn) => {
const t0 = performance.now();
fn();
const t1 = performance.now();
console.log(t1 - t0);
};
time(() => arctan(1.7320508))
time(() => arctan2(1.7320508))