Last active
May 13, 2022 06:28
-
-
Save steveruizok/4bd2341417ae707e67a36e4ef0089194 to your computer and use it in GitHub Desktop.
Get outer tangents of two circles.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function getOuterTangents( | |
x0: number, | |
y0: number, | |
r0: number, | |
x1: number, | |
y1: number, | |
r1: number | |
) { | |
const dx = x1 - x0, | |
dy = y1 - y0, | |
dist = Math.hypot(dx, dy) | |
// Circles are overlapping, no tangents | |
if (dist < Math.abs(r1 - r0)) return | |
const a0 = Math.atan2(dy, dx), | |
a1 = Math.acos((r0 - r1) / dist) | |
return [ | |
x0 + r0 * Math.cos(a0 + a1), | |
y0 + r0 * Math.sin(a0 + a1), | |
x1 + r1 * Math.cos(a0 + a1), | |
y1 + r1 * Math.sin(a0 + a1), | |
x0 + r0 * Math.cos(a0 - a1), | |
y0 + r0 * Math.sin(a0 - a1), | |
x1 + r1 * Math.cos(a0 - a1), | |
y1 + r1 * Math.sin(a0 - a1), | |
] | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Get the outer tangents of two circles. This better preserves the positions of the four tangents. | |
* | |
* @example | |
* t0______t1 t3______t2 | |
* (A) -> (B) (B) <- (A) | |
* t2 ‾‾‾‾‾t3 t1 ‾‾‾‾‾t0 | |
* | |
* @param A The first circle. | |
* @param rA The first radius. | |
* @param B The second circle. | |
* @param rB The second radius. | |
* @returns The outer tangents of the circles. | |
*/ | |
export function getCircleOuterTangents( | |
A: VecLike, | |
r0: number, | |
B: VecLike, | |
r1: number | |
): Vec2dModel[] { | |
const gamma = Math.atan((A.y - B.y) / (B.x - A.x)) | |
const beta = Math.sin((r1 - r0) / Math.hypot(A.y - B.y, A.x - B.x)) | |
let result = [ | |
{ | |
x: A.x + r0 * Math.cos(TAU - (gamma - beta)), | |
y: A.y + r0 * Math.sin(TAU - (gamma - beta)), | |
}, | |
{ | |
x: B.x + r1 * Math.cos(TAU - (gamma - beta)), | |
y: B.y + r1 * Math.sin(TAU - (gamma - beta)), | |
}, | |
{ | |
x: A.x + r0 * Math.cos(-(TAU + (gamma + beta))), | |
y: A.y + r0 * Math.sin(-(TAU + (gamma + beta))), | |
}, | |
{ | |
x: B.x + r1 * Math.cos(-(TAU + (gamma + beta))), | |
y: B.y + r1 * Math.sin(-(TAU + (gamma + beta))), | |
}, | |
] | |
if (A.x <= B.x) { | |
result = result.concat(result.splice(0, 2)) | |
} | |
return result | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment