Skip to content

Instantly share code, notes, and snippets.

@gosoccerboy5
Last active March 28, 2023 02:24
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 gosoccerboy5/0bcbbc13741911450569abe4f2b2e721 to your computer and use it in GitHub Desktop.
Save gosoccerboy5/0bcbbc13741911450569abe4f2b2e721 to your computer and use it in GitHub Desktop.
Get the equation, center, and radius of a circle given 3 points on its circumference.
/**
* circumscribe(Number x1, Number y1, Number x2, Number y2, Number x3, Number y3)
*
* Returns an object describing the circle's center, radius, and equation in Standard Form.
* Returns an error if points are overlapping or on the same line.
* Example: `circumscribe(5, -3, -1, -3, 2, -6)` returns {circumcenter: [2, -3], equation: "(x-2)²+(y+3)²=9", radius: 3}
**/
function circumscribe(x1, y1, x2, y2, x3, y3) {
// It took some math to figure this out but I'll never tell you how 😈
let s1 = (x1-x2)/(y2-y1), s2 = (x2-x3)/(y3-y2),
pts = [[x1, y1], [x2, y2], [x3, y3]];
if (arguments.length < 6 || [...arguments].some(n => typeof n !== "number")) {
return Error("CircumscribeError: Must provide exactly 3 numeric (x,y) points");
}
if (s1 === s2 || pts.some((pt, idx) => pts.some((_pt, _idx) => _idx !== idx && pt.every((v, __idx) => v === _pt[__idx]))) || [s1, s2].every(s => [Infinity, -Infinity].includes(s))) {
return Error("CircumscribeError: Points must be independent and not collinear");
}
let m1 = [(x1+x2)/2, (y1+y2)/2], m2 = [(x2+x3)/2, (y2+y3)/2];
let x = (m2[1]-m1[1]+s1*m1[0]-s2*m2[0])/(s1-s2);
let y = s1*x+m1[1]-s1*m1[0];
if (Math.abs(s1) === Infinity) [x, y] = [m1[0], s2*m1[0]+m2[1]-s2*m2[0]];
if (Math.abs(s2) === Infinity) [x, y] = [m2[0], s1*m2[0]+m1[1]-s1*m1[0]];
let radiusSquared = Math.round((Math.pow(x-x1, 2) + Math.pow(y-y1, 2))*1000)/1000;
[x, y] = [x, y].map(n => Math.round(n*1000)/1000);
let equation = `${x === 0 ? "x" : `(x${x < 0 ? "+" : ""}${-x})`}²+${y === 0 ? "y" : `(y${y < 0 ? "+" : ""}${-y})`}²=${radiusSquared}`;
return {
circumcenter: [x, y],
radius: Math.sqrt(radiusSquared),
equation,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment