RosettaCodeData/Task/Circles-of-given-radius-through-two-points/JavaScript/circles-of-given-radius-through-two-points-1.js
2017-09-25 22:28:19 +02:00

42 lines
1.3 KiB
JavaScript

const hDist = (p1, p2) => Math.hypot(...p1.map((e, i) => e - p2[i])) / 2;
const pAng = (p1, p2) => Math.atan(p1.map((e, i) => e - p2[i]).reduce((p, c) => c / p, 1));
const solveF = (p, r) => t => [r*Math.cos(t) + p[0], r*Math.sin(t) + p[1]];
const diamPoints = (p1, p2) => p1.map((e, i) => e + (p2[i] - e) / 2);
const findC = (...args) => {
const [p1, p2, s] = args;
const solve = solveF(p1, s);
const halfDist = hDist(p1, p2);
let msg = `p1: ${p1}, p2: ${p2}, r:${s} Result: `;
switch (Math.sign(s - halfDist)) {
case 0:
msg += s ? `Points on diameter. Circle at: ${diamPoints(p1, p2)}` :
'Radius Zero';
break;
case 1:
if (!halfDist) {
msg += 'Coincident point. Infinite solutions';
}
else {
let theta = pAng(p1, p2);
let theta2 = Math.acos(halfDist / s);
[1, -1].map(e => solve(theta + e * theta2)).forEach(
e => msg += `Circle at ${e} `);
}
break;
case -1:
msg += 'No intersection. Points further apart than circle diameter';
break;
}
return msg;
};
[
[[0.1234, 0.9876], [0.8765, 0.2345], 2.0],
[[0.0000, 2.0000], [0.0000, 0.0000], 1.0],
[[0.1234, 0.9876], [0.1234, 0.9876], 2.0],
[[0.1234, 0.9876], [0.8765, 0.2345], 0.5],
[[0.1234, 0.9876], [0.1234, 0.9876], 0.0]
].forEach((t,i) => console.log(`Test: ${i}: ${findC(...t)}`));