Skip to content

Instantly share code, notes, and snippets.

@SandyGifford
Created June 7, 2023 13:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SandyGifford/a9fddf107197e2f5e18691e918210acb to your computer and use it in GitHub Desktop.
Save SandyGifford/a9fddf107197e2f5e18691e918210acb to your computer and use it in GitHub Desktop.
Intersections between two circles
export type Vec2 = { x: number; y: number };
export const vecAdd = (...vs: readonly Readonly<Vec2>[]): Vec2 =>
vs.reduce(
(acc, v) => ({
x: acc.x + v.x,
y: acc.y + v.y,
}),
{ x: 0, y: 0 }
);
export const vecSub = (v1: Readonly<Vec2>, v2: Readonly<Vec2>): Vec2 => ({ x: v1.x - v2.x, y: v1.y - v2.y });
export const vecMult = (v: Readonly<Vec2>, s: number): Vec2 => ({ x: s * v.x, y: s * v.y });
export const vecLength = (v: Readonly<Vec2>): number => Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2));
export const vecDist = (v1: Readonly<Vec2>, v2: Readonly<Vec2>): number => vecLength(vecSub(v1, v2));
// https://math.stackexchange.com/questions/256100#answer-1367732
export const circleIntersections = (
c1: Readonly<Vec2>,
r1: number,
c2: Readonly<Vec2>,
r2: number
): [pos: Vec2, neg: Vec2] => {
const d = vecDist(c1, c2);
const v1 = vecAdd(
vecMult(vecAdd(c1, c2), 0.5),
vecMult(vecSub(c2, c1), (Math.pow(r1, 2) - Math.pow(r2, 2)) / (2 * Math.pow(d, 2)))
);
const v2 = vecMult(
{ x: c2.y - c1.y, y: c1.x - c2.x },
Math.sqrt(
2 * ((Math.pow(r1, 2) + Math.pow(r2, 2)) / Math.pow(d, 2)) -
Math.pow(Math.pow(r1, 2) - Math.pow(r2, 2), 2) / Math.pow(d, 4) -
1
) / 2
);
return [vecAdd(v1, v2), vecSub(v1, v2)];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment