
Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.

Exceptions

 r==0.0 should be treated as never describing circles (except in the case where the points are coincident).
 If the points are coincident then an infinite number of circles with the point on their circumference can be drawn, unless r==0.0 as well which then collapses the circles to a point.
 If the points form a diameter then return two identical circles or return a single circle, according to which is the most natural mechanism for the implementation language.
 If the points are too far apart then no circles can be drawn.


Task detail

 Write a function/subroutine/method/... that takes two points and a radius and returns the two circles through those points, or some indication of special cases where two, possibly equal, circles cannot be returned.
 Show here the output for the following 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



Related task

   Total circles area.


See also

   Finding the Center of a Circle from 2 Points and Radius from Math forum @ Drexel


 
input:  OP1=(x1,y1), OP2=(x2,y2), r
output: OC = OH + HC     
  where OH = (OP1+OP2)/2
    and HC = j*|HC| 
  where j is the unit vector rotated -90° from P1P2
    and |HC| = √(r^2 - (|P1P2|/2)^2) if exists
 
{def circleby2points
 {lambda {:x1 :y1 :x2 :y2 :r}
  {if {= :r 0}
   then radius is zero
   else {if {and {= :x1 :x2} {= :y1 :y2}}
   then same points
   else {let { {:r :r}
               {:vx {- :x2 :x1}} {:vy {- :y2 :y1}}                      // v = P1P2
               {:hx {/ {+ :x1 :x2} 2}} {:hy {/ {+ :y1 :y2} 2}} }        // h = OH
        {let { {:r :r} {:vx :vx} {:vy :vy} {:hx :hx} {:hy :hy}          // closure
               {:d {sqrt {+ {* :px :px} {* :py :py}}} } }               // d = |P1P2|
        {if {> :d {* 2 :r}}                                             // d > diam
         then no circle, points are too far apart
         else {if {= :d {* 2 :r}}                                       // d = diam
         then one circle: opposite ends of diameter with centre (:hx,:hy)
         else {let { {:r :r} {:hx :hx} {:hy :hy}                        // closure
                     {:jx {- {/ :vy :d}}} {:jy {/ :vx :d}}              // j unit -90° to P1P2
                     {:d {sqrt {- {* :r :r} {/ {* :d :d} 4}}}} }        // |HC|
              two circles: {br}({+ :hx {* :d :jx}},{+ :hy {* :d :jy}})  // OH + j*|HC|
                           {br}({- :hx {* :d :jx}},{- :hy {* :d :jy}})  // OH - j*|HC|
}}}}}}}}}
 
{circleby2points -1 0 1 0 0.5}
-> no circle:
points are too far apart
 
{circleby2points -1 0 1 0 1}
-> one circle:
opposite ends of diameter with centre (0,0)
 
{circleby2points -1 0 1 0 {sqrt 2}}
-> two circles: 
(0,1.0000000000000002) 
(0,-1.0000000000000002)
 
rosetta's task:
 
{circleby2points 0.1234 0.9876 0.8765 0.2345 2.0}
-> two circles: 
(1.8631118016581893,1.974211801658189) 
(-0.8632118016581896,-0.7521118016581892)
 
{circleby2points 0.0000 2.0000 0.0000 0.0000 1.0}
-> one circle: opposite ends of diameter with centre (0,1)
 
{circleby2points 0.1234 0.9876 0.1234 0.9876 2.0}
-> same points
 
{circleby2points 0.1234 0.9876 0.8765 0.2345 0.5}
-> no circle, points are too far apart
 
{circleby2points 0.1234 0.9876 0.1234 0.9876 0.0}
-> radius is zero
 