Last active
March 28, 2023 02:24
-
-
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.
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
/** | |
* 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