42 lines
1.3 KiB
JavaScript
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)}`));
|