--- title: Circles of given radius through two points id: 5951815dd895584b06884620 challengeType: 5 forumTopicId: 302231 localeTitle: Круги заданного радиуса через две точки --- ## Description

Учитывая две точки на плоскости и радиус, обычно через две точки могут быть проведены два круга заданного радиуса.

Исключения: радиус нуля должен рассматриваться как никогда не описывающий круги (за исключением случая, когда точки совпадают). Если точки совпадают, то может быть проведено бесконечное число кругов с точкой на их окружности, если радиус не равен нулю, а затем сворачивает круги в точку. Если точки образуют диаметр, верните один круг. Если точки слишком далеки друг от друга, круги не могут быть нарисованы. Задача: выполнить функцию, которая принимает две точки и радиус и возвращает два круга через эти точки. Для каждого результирующего круга укажите координаты для центра каждого круга, округленного до четырех десятичных цифр. Возвращает каждую координату в виде массива и координирует ее как массив массивов. Для краевых случаев возвращайте следующее: если точки находятся на диаметре, верните одну точку. Если радиус также равен нулю, верните "Radius Zero" . Если точки совпадают, верните "Coincident point. Infinite solutions" . Если точки находятся дальше друг от друга, чем диаметр, верните "No intersection. Points further apart than circle diameter" . Примеры входов:
 p1 p2 r
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
Ref: Поиск центра круга из двух точек и радиуса из математического форума @ Drexel
## Instructions
Implement a function that takes two points and a radius and returns the two circles through those points. For each resulting circle, provide the coordinates for the center of each circle rounded to four decimal digits. Return each coordinate as an array, and coordinates as an array of arrays. For edge cases, return the following: Sample inputs:
      p1                p2           r
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
## Tests
```yml tests: - text: getCircles is a function. testString: assert(typeof getCircles === 'function'); - text: getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0) should return [[1.8631, 1.9742], [-0.8632, -0.7521]]. testString: assert.deepEqual(getCircles(...testCases[0]), answers[0]); - text: getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0) should return [0, 1] testString: assert.deepEqual(getCircles(...testCases[1]), answers[1]); - text: getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0) should return Coincident point. Infinite solutions testString: assert.deepEqual(getCircles(...testCases[2]), answers[2]); - text: getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5) should return No intersection. Points further apart than circle diameter testString: assert.deepEqual(getCircles(...testCases[3]), answers[3]); - text: getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0) should return Radius Zero testString: assert.deepEqual(getCircles(...testCases[4]), answers[4]); ```
## Challenge Seed
```js function getCircles(...args) { // Good luck! return true; } ```
### After Tests
```js const testCases = [ [[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] ]; const answers = [ [[1.8631, 1.9742], [-0.8632, -0.7521]], [0, 1], 'Coincident point. Infinite solutions', 'No intersection. Points further apart than circle diameter', 'Radius Zero' ]; ```
## Solution
```js 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 => [parseFloat((r * Math.cos(t) + p[0]).toFixed(4)), parseFloat((r * Math.sin(t) + p[1]).toFixed(4))]; const diamPoints = (p1, p2) => p1.map((e, i) => parseFloat((e + (p2[i] - e) / 2).toFixed(4))); function getCircles(...args) { const [p1, p2, s] = args; const solve = solveF(p1, s); const halfDist = hDist(p1, p2); let msg = []; switch (Math.sign(s - halfDist)) { case 0: msg = s ? diamPoints(p1, p2) : 'Radius Zero'; break; case 1: if (!halfDist) { msg = 'Coincident point. Infinite solutions'; } else { const theta = pAng(p1, p2); const theta2 = Math.acos(halfDist / s); [1, -1].map(e => solve(theta + e * theta2)).forEach( e => msg.push(e)); } break; case -1: msg = 'No intersection. Points further apart than circle diameter'; break; default: msg = 'Reached the default'; } return msg; } ```