Circles of given radius through two points: Difference between revisions

m
→‎{{header|11l}}: Named tuple as a base type
m (→‎{{header|11l}}: Named tuple as a base type)
 
(65 intermediate revisions by 31 users not shown)
Line 1:
[[Category:Geometry]]
{{task}}
[[File:2 circles through 2 points.jpg|500px650px||right|2 circles with a given radius through 2 points in 2D space.]]
 
Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.
Line 22 ⟶ 23:
</pre>
 
 
;Ref:
;Related task:
* [http://mathforum.org/library/drmath/view/53027.html Finding the Center of a Circle from 2 Points and Radius] from Math forum @ Drexel
* &nbsp; [[Total circles area]].
 
 
;See also:
* &nbsp; [http://mathforum.org/library/drmath/view/53027.html Finding the Center of a Circle from 2 Points and Radius] from Math forum @ Drexel
<br><br>
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">T Circle((Float x, Float y, Float r))
F String()
R ‘Circle(x=#.6, y=#.6, r=#.6)’.format(.x, .y, .r)
 
T Error
String msg
F (msg)
.msg = msg
 
F circles_from_p1p2r(p1, p2, r) X(Error)
‘Following explanation at http://mathforum.org/library/drmath/view/53027.html’
I r == 0.0
X Error(‘radius of zero’)
V (x1, y1) = p1
V (x2, y2) = p2
I p1 == p2
X Error(‘coincident points gives infinite number of Circles’)
V (dx, dy) = (x2 - x1, y2 - y1)
V q = sqrt(dx ^ 2 + dy ^ 2)
I q > 2.0 * r
X Error(‘separation of points > diameter’)
V (x3, y3) = ((x1 + x2) / 2, (y1 + y2) / 2)
V d = sqrt(r ^ 2 - (q / 2) ^ 2)
V c1 = Circle(x' x3 - d * dy / q,
y' y3 + d * dx / q,
r' abs(r))
V c2 = Circle(x' x3 + d * dy / q,
y' y3 - d * dx / q,
r' abs(r))
R (c1, c2)
 
L(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)]
print("Through points:\n #.,\n #.\n and radius #.6\nYou can construct the following circles:".format(p1, p2, r))
X.try
V (c1, c2) = circles_from_p1p2r(p1, p2, r)
print(" #.\n #.\n".format(c1, c2))
X.handle Error v
print(" ERROR: #.\n".format(v.msg))</syntaxhighlight>
 
{{out}}
<pre>
Through points:
(0.1234, 0.9876),
(0.8765, 0.2345)
and radius 2.000000
You can construct the following circles:
Circle(x=1.863112, y=1.974212, r=2.000000)
Circle(x=-0.863212, y=-0.752112, r=2.000000)
 
Through points:
(0, 2),
(0, 0)
and radius 1.000000
You can construct the following circles:
Circle(x=0.000000, y=1.000000, r=1.000000)
Circle(x=0.000000, y=1.000000, r=1.000000)
 
Through points:
(0.1234, 0.9876),
(0.1234, 0.9876)
and radius 2.000000
You can construct the following circles:
ERROR: coincident points gives infinite number of Circles
 
Through points:
(0.1234, 0.9876),
(0.8765, 0.2345)
and radius 0.500000
You can construct the following circles:
ERROR: separation of points > diameter
 
Through points:
(0.1234, 0.9876),
(0.1234, 0.9876)
and radius 0.000000
You can construct the following circles:
ERROR: radius of zero
</pre>
 
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT"
 
PROC Circles(CHAR ARRAY sx1,sy1,sx2,sy2,sr)
REAL x1,y1,x2,y2,r,x,y,bx,by,pb,cb,xx,yy
REAL two,tmp1,tmp2,tmp3
 
ValR(sx1,x1) ValR(sy1,y1)
ValR(sx2,x2) ValR(sy2,y2)
ValR(sr,r) IntToReal(2,two)
 
Print("p1=(") PrintR(x1) Put(32)
PrintR(y1) Print(") p2=(")
PrintR(x2) Put(32) PrintR(y2)
Print(") r=") PrintR(r) Print(" -> ")
 
IF RealEqual(r,rzero) THEN
PrintE("Radius is zero, no circles") PutE()
RETURN
FI
 
RealSub(x2,x1,tmp1) ;tmp1=x2-x1
RealDiv(tmp1,two,x) ;x=(x2-x1)/2
 
RealSub(y2,y1,tmp1) ;tmp1=y2-y1
RealDiv(tmp1,two,y) ;y=(y2-y1)/2
 
RealAdd(x1,x,bx) ;bx=x1+x
RealAdd(y1,y,by) ;bx=x1+x
 
RealMult(x,x,tmp1) ;tmp1=x^2
RealMult(y,y,tmp2) ;tmp2=y^2
RealAdd(tmp1,tmp2,tmp3) ;tmp3=x^2+y^2
Sqrt(tmp3,pb) ;pb=sqrt(x^2+y^2)
 
IF RealEqual(pb,rzero) THEN
PrintE("Infinite circles")
ELSEIF RealGreater(pb,r) THEN
PrintE("Points are too far, no circles")
ELSE
RealMult(r,r,tmp1) ;tmp1=r^2
RealMult(pb,pb,tmp2) ;tmp2=pb^2
RealSub(tmp1,tmp2,tmp3) ;tmp3=r^2-pb^2
Sqrt(tmp3,cb) ;cb=sqrt(r^2-pb^2)
 
RealMult(y,cb,tmp1) ;tmp1=y*cb
RealDiv(tmp1,pb,xx) ;xx=y*cb/pb
 
RealMult(x,cb,tmp1) ;tmp1=x*cb
RealDiv(tmp1,pb,yy) ;yy=x*cb/pb
 
RealSub(bx,xx,tmp1) ;tmp1=bx-xx
Print("c1=(") PrintR(tmp1) Put(32)
 
RealAdd(by,yy,tmp1) ;tmp1=by+yy
PrintR(tmp1) Print(") c2=(")
 
RealAdd(bx,xx,tmp1) ;tmp1=bx+xx
PrintR(tmp1) Put(32)
 
RealSub(by,yy,tmp1) ;tmp1=by-yy
PrintR(tmp1) PrintE(")")
FI
PutE()
RETURN
 
PROC Main()
Put(125) PutE() ;clear the screen
MathInit()
Circles("0.1234","0.9876","0.8765","0.2345","2.0")
Circles("0.0000","2.0000","0.0000","0.0000","1.0")
Circles("0.1234","0.9876","0.1234","0.9876","2.0")
Circles("0.1234","0.9876","0.8765","0.2345","0.5")
Circles("0.1234","0.9876","0.1234","0.9876","0.0")
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Circles_of_given_radius_through_two_points.png Screenshot from Atari 8-bit computer]
<pre>
p1=(.1234 .9876) p2=(.8765 .2345) r=2 -> c1=(1.86311176 1.97421176) c2=(-0.86321176 -0.75211176)
 
p1=(0 2) p2=(0 0) r=1 -> c1=(0 1) c2=(0 1)
 
p1=(.1234 .9876) p2=(.1234 .9876) r=2 -> Infinite circles
 
p1=(.1234 .9876) p2=(.8765 .2345) r=.5 -> c1=(1.19528365 1.30638365) c2=(-0.1953836533 -0.0842836533)
 
p1=(.1234 .9876) p2=(.1234 .9876) r=0 -> Radius is zero, no circles
</pre>
=={{header|ALGOL 68}}==
Calculations based on the C solution.
<langsyntaxhighlight lang="algol68"># represents a point #
MODE POINT = STRUCT( REAL x, REAL y );
# returns TRUE if p1 is the same point as p2, FALSE otherwise #
Line 134 ⟶ 315:
print circles( 0.1234, 0.9876, 0.1234, 0.9876, 2.0 );
print circles( 0.1234, 0.9876, 0.8765, 0.2345, 0.5 );
print circles( 0.1234, 0.9876, 0.1234, 0.9876, 0.0 )</langsyntaxhighlight>
{{out}}
<pre>
Line 143 ⟶ 324:
One circle : radius: 0.0000 @( 0.1234, 0.9876)
</pre>
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">getPoint: function [p]-> ~{(x: |p\0|, y: |p\1|)}
getCircle: function [c]-> ~{(x: |c\0|, y: |c\1|, r: |c\2|)}
 
circles: function [p1, p2, r][
if r = 0 -> return "radius of zero"
if p1 = p2 -> return "coincident points gives infinite number of circles"
 
[dx, dy]: @[p2\0 - p1\0, p2\1 - p1\1]
q: sqrt add dx*dx dy*dy
if q > 2*r -> return "separation of points > diameter"
 
p3: @[(p1\0 + p2\0)/ 2, (p1\1 + p2\1) / 2]
d: sqrt (r*r) - (q/2)*(q/2)
return @[
@[(p3\0 - d*dy/q), (p3\1 + d*dx/q), abs r],
@[(p3\0 + d*dy/q), (p3\1 - d*dx/q), abs r]
]
]
 
loop [
[[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]
] 'tr [
[p1, p2, r]: tr
print ["Through points:\n " getPoint p1 "\n " getPoint p2]
print ["and radius" (to :string r)++"," "you can construct the following circles:"]
if? string? cic: <= circles p1 p2 r -> print [" ERROR:" cic]
else [
[c1, c2]: cic
print [" " getCircle c1]
print [" " getCircle c2]
]
print ""
]</syntaxhighlight>
 
{{out}}
 
<pre>Through points:
(x: 0.1234, y: 0.9876)
(x: 0.8764999999999999, y: 0.2345)
and radius 2.0, you can construct the following circles:
(x: 1.863111801658189, y: 1.974211801658189, r: 2.0)
(x: -0.8632118016581896, y: -0.7521118016581892, r: 2.0)
 
Through points:
(x: 0.0, y: 2.0)
(x: 0.0, y: 0.0)
and radius 1.0, you can construct the following circles:
(x: 0.0, y: 1.0, r: 1.0)
(x: 0.0, y: 1.0, r: 1.0)
 
Through points:
(x: 0.1234, y: 0.9876)
(x: 0.1234, y: 0.9876)
and radius 2.0, you can construct the following circles:
ERROR: coincident points gives infinite number of circles
 
Through points:
(x: 0.1234, y: 0.9876)
(x: 0.8764999999999999, y: 0.2345)
and radius 0.5, you can construct the following circles:
ERROR: separation of points > diameter
 
Through points:
(x: 0.1234, y: 0.9876)
(x: 0.1234, y: 0.9876)
and radius 0.0, you can construct the following circles:
ERROR: radius of zero</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">CircleCenter(x1, y1, x2, y2, r){
d := sqrt((x2-x1)**2 + (y2-y1)**2)
x3 := (x1+x2)/2 , y3 := (y1+y2)/2
Line 161 ⟶ 415:
return "no solution"
return cx1 "," cy1 " & " cx2 "," cy2
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">data =
(
0.1234 0.9876 0.8765 0.2345 2.0
Line 175 ⟶ 429:
obj := StrSplit(A_LoopField, " ")
MsgBox, % CircleCenter(obj[1], obj[2], obj[3], obj[4], obj[5])
}</langsyntaxhighlight>
{{out}}
<pre>0.1234 0.9876 0.8765 0.2345 2.0 > 1.863112,1.974212 & -0.863212,-0.752112
Line 184 ⟶ 438:
</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f CIRCLES_OF_GIVEN_RADIUS_THROUGH_TWO_POINTS.AWK
# converted from PL/I
BEGIN {
split("0.1234,0,0.1234,0.1234,0.1234",m1x,",")
split("0.9876,2,0.9876,0.9876,0.9876",m1y,",")
split("0.8765,0,0.1234,0.8765,0.1234",m2x,",")
split("0.2345,0,0.9876,0.2345,0.9876",m2y,",")
leng = split("2,1,2,0.5,0",r,",")
print(" x1 y1 x2 y2 r cir1x cir1y cir2x cir2y")
print("------- ------- ------- ------- ---- ------- ------- ------- -------")
for (i=1; i<=leng; i++) {
printf("%7.4f %7.4f %7.4f %7.4f %4.2f %s\n",m1x[i],m1y[i],m2x[i],m2y[i],r[i],main(m1x[i],m1y[i],m2x[i],m2y[i],r[i]))
}
exit(0)
}
function main(m1x,m1y,m2x,m2y,r, bx,by,pb,x,x1,y,y1) {
if (r == 0) { return("radius of zero gives no circles") }
x = (m2x - m1x) / 2
y = (m2y - m1y) / 2
bx = m1x + x
by = m1y + y
pb = sqrt(x^2 + y^2)
if (pb == 0) { return("coincident points give infinite circles") }
if (pb > r) { return("points are too far apart for the given radius") }
cb = sqrt(r^2 - pb^2)
x1 = y * cb / pb
y1 = x * cb / pb
return(sprintf("%7.4f %7.4f %7.4f %7.4f",bx-x1,by+y1,bx+x1,by-y1))
}
</syntaxhighlight>
{{out}}
<pre>
x1 y1 x2 y2 r cir1x cir1y cir2x cir2y
------- ------- ------- ------- ---- ------- ------- ------- -------
0.1234 0.9876 0.8765 0.2345 2.00 1.8631 1.9742 -0.8632 -0.7521
0.0000 2.0000 0.0000 0.0000 1.00 0.0000 1.0000 0.0000 1.0000
0.1234 0.9876 0.1234 0.9876 2.00 coincident points give infinite circles
0.1234 0.9876 0.8765 0.2345 0.50 points are too far apart for the given radius
0.1234 0.9876 0.1234 0.9876 0.00 radius of zero gives no circles
</pre>
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{works with|FreeBASIC}}
{{trans|Liberty BASIC}}
<lang freebasic>Type Point
<syntaxhighlight lang="basic256">
As Double x,y
function twoCircles(x1, y1, x2, y2, radio)
Declare Property length As Double
if x1 = x2 and y1 = y2 then #Si los puntos coinciden
End Type
if radio = 0 then #a no ser que radio=0
print "Los puntos son los mismos "
return ""
else
print "Hay cualquier número de círculos a través de un solo punto ("; x1; ", "; y1; ") de radio "; int(radio)
return ""
end if
end if
r2 = sqr((x1-x2)^2+(y1-y2)^2) / 2 #distancia media entre puntos
if radio < r2 then
print "Los puntos están demasiado separados ("; 2*r2; ") - no hay círculos de radio "; int(radio)
return ""
end if
 
#si no, calcular dos centros
Property point.length As Double
cx = (x1+x2) / 2 #punto medio
Return Sqr(x*x+y*y)
cy = (y1+y2) / 2
End Property
#debe moverse desde el punto medio a lo largo de la perpendicular en dd2
dd2 = sqr(radio^2 - r2^2) #distancia perpendicular
dx1 = x2-cx #vector al punto medio
dy1 = y2-cy
dx = 0-dy1 / r2*dd2 #perpendicular:
dy = dx1 / r2*dd2 #rotar y escalar
print " -> Circulo 1 ("; cx+dy; ", "; cy+dx; ")" #dos puntos, con (+)
print " -> Circulo 2 ("; cx-dy; ", "; cy-dx; ")" #y (-)
return ""
end function
 
# p1 p2 radio
Sub circles(p1 As Point,p2 As Point,radius As Double)
x1 = 0.1234 : y1 = 0.9876 : x2 = 0.8765 : y2 = 0.2345 : radio = 2.0
Print "Points ";"("&p1.x;","&p1.y;"),("&p2.x;","&p2.y;")";", Rad ";radius
print "Puntos "; "("; x1; ","; y1; "), ("; x2; ","; y2; ")"; ", Radio "; int(radio)
Var ctr=Type<Point>((p1.x+p2.x)/2,(p1.y+p2.y)/2)
print twoCircles (x1, y1, x2, y2, radio)
Var half=Type<Point>(p1.x-ctr.x,p1.y-ctr.y)
x1 = 0.0000 : y1 = 2.0000 : x2 = 0.0000 : y2 = 0.0000 : radio = 1.0
Var lenhalf=half.length
print "Puntos "; "("; x1; ","; y1; "), ("; x2; ","; y2; ")"; ", Radio "; int(radio)
If radius<lenhalf Then Print "Can't solve":Print:Exit Sub
print twoCircles (x1, y1, x2, y2, radio)
If lenhalf=0 Then Print "Points are the same":Print:Exit Sub
x1 = 0.1234 : y1 = 0.9876 : x2 = 0.12345 : y2 = 0.9876 : radio = 2.0
Var dist=Sqr(radius^2-lenhalf^2)/lenhalf
print "Puntos "; "("; x1; ","; y1; "), ("; x2; ","; y2; ")"; ", Radio "; int(radio)
Var rot= Type<Point>(-dist*(p1.y-ctr.y) +ctr.x,dist*(p1.x-ctr.x) +ctr.y)
print twoCircles (x1, y1, x2, y2, radio)
Print " -> Circle 1 ("&rot.x;","&rot.y;")"
x1 = 0.1234 : y1 = 0.9876 : x2 = 0.8765 : y2 = 0.2345 : radio = 0.5
rot= Type<Point>(-(rot.x-ctr.x) +ctr.x,-((rot.y-ctr.y)) +ctr.y)
print "Puntos "; "("; x1; ","; y1; "), ("; x2; ","; y2; ")"; ", Radio "; int(radio)
Print" -> Circle 2 ("&rot.x;","&rot.y;")"
print twoCircles (x1, y1, x2, y2, radio)
Print
x1 = 0.1234 : y1 = 0.9876 : x2 = 1234 : y2 = 0.9876 : radio = 0.0
End Sub
print "Puntos "; "("; x1; ","; y1; "), ("; x2; ","; y2; ")"; ", Radio "; int(radio)
 
print twoCircles (x1, y1, x2, y2, radio)
 
end
Dim As Point p1=(.1234,.9876),p2=(.8765,.2345)
</syntaxhighlight>
circles(p1,p2,2)
p1=Type<Point>(0,2):p2=Type<Point>(0,0)
circles(p1,p2,1)
p1=Type<Point>(.1234,.9876):p2=p1
circles(p1,p2,2)
p1=Type<Point>(.1234,.9876):p2=Type<Point>(.8765,.2345)
circles(p1,p2,.5)
p1=Type<Point>(.1234,.9876):p2=p1
circles(p1,p2,0)
 
Sleep</lang>
{{out}}
<pre>Points (0.1234,0.9876),(0.8765,0.2345), Rad 2
-> Circle 1 (-0.8632118016581893,-0.7521118016581889)
-> Circle 2 (1.863111801658189,1.974211801658189)
 
Points (0,2),(0,0), Rad 1
-> Circle 1 (0,1)
-> Circle 2 (0,1)
 
Points (0.1234,0.9876),(0.1234,0.9876), Rad 2
Points are the same
 
Points (0.1234,0.9876),(0.8765,0.2345), Rad 0.5
Can't solve
 
Points (0.1234,0.9876),(0.1234,0.9876), Rad 0
Points are the same</pre>
 
=={{header|C}}==
<syntaxhighlight lang="c">#include<stdio.h>
<lang C>
 
#include<stdio.h>
#include<math.h>
 
Line 287 ⟶ 577:
int main()
{
int i;
 
point cases[] =
{ {0.1234, 0.9876}, {0.8765, 0.2345},
{0.0000, 2.0000}, {0.0000, 0.0000},
{0.1234, 0.9876}, {0.1234, 0.9876},
{0.1234, 0.9876}, {0.8765, 0.2345},
{0.1234, 0.9876}, {0.1234, 0.9876}
};
 
double radii[] = {2.0,1.0,2.0,0.5,0.0};
 
for(i=0;i<5;i++)
{
printf("\nCase %d)",i+1);
findCircles(cases[2*i],cases[2*i+1],radii[i]);
}
}
 
return 0;
}
</syntaxhighlight>
</lang>
{{out|test run}}
<pre>
Line 322 ⟶ 612:
No circles can be drawn through (0.1234,0.9876)
</pre>
=={{header|C sharp|C#}}==
 
 
=={{header|C sharp}}==
{{works with|C sharp|6}}
<langsyntaxhighlight lang="csharp">using System;
public class CirclesOfGivenRadiusThroughTwoPoints
{
Line 397 ⟶ 685:
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 410 ⟶ 698:
Points (0.1234, 0.9876) and (0.1234, 0.9876) with radius 0:
(0.1234, 0.9876)</pre>
 
=={{header|C++}}==
{{works with|C++11}}
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <cmath>
Line 441 ⟶ 728:
if(half_distance > r) return std::make_tuple(NONE, ans1, ans2);
if(half_distance - r == 0) return std::make_tuple(ONE_DIAMETER, center, ans2);
double root = std::hypotsqrt(pow(r, 2.l) - pow(half_distance, 2.l)) / distance(p1, p2);
ans1.x = center.x + root * (p1.y - p2.y);
ans1.y = center.y + root * (p2.x - p1.x);
Line 477 ⟶ 764:
for(int i = 0; i < size; ++i)
print(find_circles(points[i*2], points[i*2 + 1], radius[i]));
}</langsyntaxhighlight>
{{out}}
<pre>
Two solutions: 1.9634486311 21.0745497421 and -0.963536863212 -0.852436752112
Only one solution: 0 1
Infinitely many circles can be drawn
Line 489 ⟶ 776:
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.typecons, std.math;
 
class ValueException : Exception {
Line 550 ⟶ 837:
writefln(" ERROR: %s\n", v.msg);
}
}</langsyntaxhighlight>
{{out}}
<pre>Through points:
Line 579 ⟶ 866:
ERROR: radius of zero
</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| System.Types}}
{{libheader| System.Math}}
{{Trans|C}}
<syntaxhighlight lang="delphi">
program Circles_of_given_radius_through_two_points;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
System.Types,
System.Math;
 
const
Cases: array[0..9] of TPointF = ((
x: 0.1234;
y: 0.9876
), (
x: 0.8765;
y: 0.2345
), (
x: 0.0000;
y: 2.0000
), (
x: 0.0000;
y: 0.0000
), (
x: 0.1234;
y: 0.9876
), (
x: 0.1234;
y: 0.9876
), (
x: 0.1234;
y: 0.9876
), (
x: 0.8765;
y: 0.2345
), (
x: 0.1234;
y: 0.9876
), (
x: 0.1234;
y: 0.9876
));
radii: array of double = [2.0, 1.0, 2.0, 0.5, 0.0];
 
procedure FindCircles(p1, p2: TPointF; radius: double);
var
separation, mirrorDistance: double;
begin
separation := p1.Distance(p2);
if separation = 0.0 then
begin
if radius = 0 then
write(format(#10'No circles can be drawn through (%.4f,%.4f)', [p1.x, p1.y]))
else
write(format(#10'Infinitely many circles can be drawn through (%.4f,%.4f)',
[p1.x, p1.y]));
exit;
end;
 
if separation = 2 * radius then
begin
write(format(#10'Given points are opposite ends of a diameter of the circle with center (%.4f,%.4f) and radius %.4f',
[(p1.x + p2.x) / 2, (p1.y + p2.y) / 2, radius]));
exit;
end;
 
if separation > 2 * radius then
begin
write(format(#10'Given points are farther away from each other than a diameter of a circle with radius %.4f',
[radius]));
exit;
end;
 
mirrorDistance := sqrt(Power(radius, 2) - Power(separation / 2, 2));
write(#10'Two circles are possible.');
write(format(#10'Circle C1 with center (%.4f,%.4f), radius %.4f and Circle C2 with center (%.4f,%.4f), radius %.4f',
[(p1.x + p2.x) / 2 + mirrorDistance * (p1.y - p2.y) / separation, (p1.y + p2.y)
/ 2 + mirrorDistance * (p2.x - p1.x) / separation, radius, (p1.x + p2.x) / 2
- mirrorDistance * (p1.y - p2.y) / separation, (p1.y + p2.y) / 2 -
mirrorDistance * (p2.x - p1.x) / separation, radius]));
 
end;
 
begin
for var i := 0 to 4 do
begin
write(#10'Case ', i + 1,')');
findCircles(cases[2 * i], cases[2 * i + 1], radii[i]);
end;
readln;
end.</syntaxhighlight>
=={{header|EasyLang}}==
{{trans|AWK}}
<syntaxhighlight>
func$ fmt a b .
return "(" & a & " " & b & ")"
.
proc test m1x m1y m2x m2y r . .
print "Points: " & fmt m1x m1y & " " & fmt m2x m2y & " Radius: " & r
if r = 0
print "Radius of zero gives no circles"
print ""
return
.
x = (m2x - m1x) / 2
y = (m2y - m1y) / 2
bx = m1x + x
by = m1y + y
pb = sqrt (x * x + y * y)
if pb = 0
print "Coincident points give infinite circles"
print ""
return
.
if pb > r
print "Points are too far apart for the given radius"
print ""
return
.
cb = sqrt (r * r - pb * pb)
x1 = y * cb / pb
y1 = x * cb / pb
print "Circles: " & fmt (bx - x1) (by + y1) & " " & fmt (bx + x1) (by - y1)
print ""
.
test 0.1234 0.9876 0.8765 0.2345 2.0
test 0.0000 2.0000 0.0000 0.0000 1.0
test 0.1234 0.9876 0.1234 0.9876 2.0
test 0.1234 0.9876 0.8765 0.2345 0.5
test 0.1234 0.9876 0.1234 0.9876 0.0
</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule RC do
def circle(p, p, r) when r>0.0 do
raise ArgumentError, message: "Infinite number of circles, points coincide."
Line 619 ⟶ 1,042:
end
IO.puts ""
end)</langsyntaxhighlight>
 
{{out}}
Line 659 ⟶ 1,082:
 
=={{header|ERRE}}==
<syntaxhighlight lang="text">
PROGRAM CIRCLES
 
Line 711 ⟶ 1,134:
END FOR
END PROGRAM
</syntaxhighlight>
</lang>
=={{header|F Sharp|F#}}==
<syntaxhighlight lang="fsharp">open System
 
let add (a:double, b:double) (x:double, y:double) = (a + x, b + y)
let sub (a:double, b:double) (x:double, y:double) = (a - x, b - y)
let magSqr (a:double, b:double) = a * a + b * b
let mag a:double = Math.Sqrt(magSqr a)
let mul (a:double, b:double) c = (a * c, b * c)
let div2 (a:double, b:double) c = (a / c, b / c)
let perp (a:double, b:double) = (-b, a)
let norm a = div2 a (mag a)
 
let circlePoints p q (radius:double) =
let diameter = radius * 2.0
let pq = sub p q
let magPQ = mag pq
let midpoint = div2 (add p q) 2.0
let halfPQ = magPQ / 2.0
let magMidC = Math.Sqrt(Math.Abs(radius * radius - halfPQ * halfPQ))
let midC = mul (norm (perp pq)) magMidC
let center1 = add midpoint midC
let center2 = sub midpoint midC
if radius = 0.0 then None
else if p = q then None
else if diameter < magPQ then None
else Some (center1, center2)
 
[<EntryPoint>]
let main _ =
printfn "%A" (circlePoints (0.1234, 0.9876) (0.8765, 0.2345) 2.0)
printfn "%A" (circlePoints (0.0, 2.0) (0.0, 0.0) 1.0)
printfn "%A" (circlePoints (0.1234, 0.9876) (0.1234, 0.9876) 2.0)
printfn "%A" (circlePoints (0.1234, 0.9876) (0.8765, 0.2345) 0.5)
printfn "%A" (circlePoints (0.1234, 0.9876) (0.1234, 0.1234) 0.0)
 
0 // return an integer exit code</syntaxhighlight>
{{out}}
<pre>Some ((-0.8632118017, -0.7521118017), (1.863111802, 1.974211802))
Some ((0.0, 1.0), (0.0, 1.0))
<null>
<null>
<null></pre>
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: accessors combinators combinators.short-circuit
formatting io kernel literals locals math math.distances
math.functions prettyprint sequences strings ;
IN: rosetta-code.circles
DEFER: find-circles
 
! === Input ====================================================
 
TUPLE: input p1 p2 r ;
 
CONSTANT: test-cases {
T{ input f { 0.1234 0.9876 } { 0.8765 0.2345 } 2 }
T{ input f { 0 2 } { 0 0 } 1 }
T{ input f { 0.1234 0.9876 } { 0.1234 0.9876 } 2 }
T{ input f { 0.1234 0.9876 } { 0.8765 0.2345 } 0.5 }
T{ input f { 0.1234 0.9876 } { 0.1234 0.9876 } 0 }
}
 
! === Edge case handling =======================================
 
CONSTANT: infinite
"there could be an infinite number of circles."
 
CONSTANT: too-far
"points are too far apart to form circles."
 
: coincident? ( input -- ? ) [ p1>> ] [ p2>> ] bi = ;
 
: degenerate? ( input -- ? )
{ [ r>> zero? ] [ coincident? ] } 1&& ;
 
: infinite? ( input -- ? )
{ [ r>> zero? not ] [ coincident? ] } 1&& ;
 
: too-far? ( input -- ? )
[ r>> 2 * ] [ p1>> ] [ p2>> ] tri euclidian-distance < ;
 
: degenerate ( input -- str )
p1>> [ first ] [ second ] bi
"one degenerate circle found at (%.4f, %.4f).\n" sprintf ;
 
: check-input ( input -- obj )
{
{ [ dup infinite? ] [ drop infinite ] }
{ [ dup too-far? ] [ drop too-far ] }
{ [ dup degenerate? ] [ degenerate ] }
[ find-circles ]
} cond ;
 
! === Program Logic ============================================
 
:: (circle-coords) ( a b c r q quot -- x )
a r sq q 2 / sq - sqrt b c - * q / quot call ; inline
 
: circle-coords ( quot -- x y )
[ + ] over [ - ] [ [ call ] dip (circle-coords) ] 2bi@ ;
inline
 
:: find-circles ( input -- circles )
input [ r>> ] [ p1>> ] [ p2>> ] tri :> ( r p1 p2 )
p1 p2 [ [ first ] [ second ] bi ] bi@ :> ( x1 y1 x2 y2 )
x1 x2 y1 y2 [ + 2 / ] 2bi@ :> ( x3 y3 )
p1 p2 euclidian-distance :> q
[ x3 y1 y2 r q ]
[ y3 x2 x1 r q ] [ circle-coords ] bi@ :> ( x w y z )
{ x y } { w z } = { { x y } } { { w z } { x y } } ? ;
 
! === Output ===================================================
 
: .point ( seq -- )
[ first ] [ second ] bi "(%.4f, %.4f)" printf ;
 
: .given ( input -- )
[ r>> ] [ p2>> ] [ p1>> ] tri
"Given points " write .point ", " write .point
", and radius %.2f,\n" printf ;
 
: .one ( seq -- )
first "one circle found at " write .point "." print ;
 
: .two ( seq -- )
[ first ] [ second ] bi "two circles found at " write
.point " and " write .point "." print ;
 
: .circles ( seq -- ) dup length 1 = [ .one ] [ .two ] if ;
 
! === Main word ================================================
 
: circles-demo ( -- )
test-cases [
dup .given check-input dup string?
[ print ] [ .circles ] if nl
] each ;
 
MAIN: circles-demo</syntaxhighlight>
{{out}}
<pre>
Given points (0.1234, 0.9876), (0.8765, 0.2345), and radius 2.00,
two circles found at (1.8631, 1.9742) and (-0.8632, -0.7521).
 
Given points (0.0000, 2.0000), (0.0000, 0.0000), and radius 1.00,
one circle found at (0.0000, 1.0000).
 
Given points (0.1234, 0.9876), (0.1234, 0.9876), and radius 2.00,
there could be an infinite number of circles.
 
Given points (0.1234, 0.9876), (0.8765, 0.2345), and radius 0.50,
points are too far apart to form circles.
 
Given points (0.1234, 0.9876), (0.1234, 0.9876), and radius 0.00,
one degenerate circle found at (0.1234, 0.9876).
</pre>
=={{header|Fortran}}==
<syntaxhighlight lang="fortran">
{{incorect|Fortran|The coordinates for the first example are wrong.}}
<lang fortran>
! Implemented by Anant Dixit (Nov. 2014)
! Transpose elements in find_center to obtain correct results. R.N. McLean (Dec 2017)
program circles
implicit none
Line 810 ⟶ 1,387:
subroutine find_center(P1,P2,R,Center)
implicit none
double precision :: P1(2), P2(2), MP(2), Center(2,2), R, dm, dd
MP = (P1 + P2)/2.0d0
dm = sqrt( (P1(1) - P2(1))**2 + (P1(2) - P2(2))**2 )
dd = sqrt(R**2 - (dm/2.0d0)**2)
Center(1,1) = MP(1) - dd*(P2(2) - P1(2))/dm
Center(1,2) = MP(2) + dd*(P2(1) - P1(1))/dm
 
Center(12,1) = MP(1) + sqrt(R**2 - (dm/2.0d0)**2)dd*(P2(2) - P1(2))/dm
Center(12,2) = MP(2) + sqrt(R**2 - (dm/2.0d0)**2)dd*(P2(1) - P1(1))/dm
end subroutine find_center</syntaxhighlight>
 
Center(2,1) = MP(1) - sqrt(R**2 - (dm/2.0d0)**2)*(P2(2)-P1(2))/dm
Center(2,2) = MP(2) - sqrt(R**2 - (dm/2.0d0)**2)*(P2(1)-P1(1))/dm
end subroutine find_center
</lang>
 
{{out}}
Line 829 ⟶ 1,405:
Radius : 2.0000
Two distinct circles found.
Center1 : -0 1.86328631 1.9742
Center2 : 1-0.86318632 -0.7521
 
 
Line 858 ⟶ 1,434:
</pre>
 
===Using complex numbers===
Fortran 66 made standard the availability of complex number arithmetic. This version however takes advantage of facilities offered in F90 so as to perform some array-based arithmetic, though the opportunities in this small routine are thin: two statements become one (look for CMPLX). More seriously, the MODULE facility allows the definition of an array SQUAWK which contains an explanatory text associated with each return code. The routine has a troublesome variety of possible odd conditions to report. An older approach would be to have a return message CHARACTER variable to present the remark, at the cost of filling up that variable with text every time. By returning an integer code, less effort is required, but there is no explication of the return codes. One could still have an array of messages (and prior to F90, array index counting started at one only, so no starting with -3 for errorish codes) but making that array available would require some sort of COMMON storage. The MODULE facility eases this problem.
<syntaxhighlight lang="fortran"> MODULE GEOMETRY !Limited scope.
CHARACTER*(*) SQUAWK(-3:2) !Holds a schedule of complaints.
PARAMETER (SQUAWK = (/ !According to what might go wrong.
3 "No circles: points are more than 2R apart.",
2 "Innumerable circles: co-incident points, R > 0.",
1 "One 'circle', centred on the co-incident points. R is zero!",
o "No circles! R is negative!",
1 "One circle: points are 2R apart.",
2 "Two circles."/)) !This last is the hoped-for state.
CONTAINS !Now for the action.
SUBROUTINE BUBBLE(P,R,N) !Finds circles of radius R passing through two points.
COMPLEX P(2) !The two points. Results returned here.
REAL R !The specified radius.
INTEGER N !Indicates how many centres are valid.
COMPLEX MID,DP !Geometrical assistants.
DP = (P(2) - P(1))/2 !Or, the other way around.
D = ABS(DP) !Half the separation is useful.
IF (R.LT.0) THEN !Is the specified radius silly?
N = 0 !Yes. No circles, then.
ELSE IF (D.EQ.0) THEN !Any distance between the points?
IF (R.EQ.0) THEN !No. Zero radius?
N = -1 !Yes. So a degenerate "circle" of zero radius.
ELSE !A negative radius being tested for above,
N = -2 !A swirl of circles around the midpoint.
END IF !So much for co-incident points.
ELSE IF (D.GT.R) THEN !Points too far apart?
N = -3 !A circle of radius R can't reach them.
ELSE IF (D.EQ.R) THEN !Maximum separation for R?
N = 1 !Yes. The two circles lie atop each other.
P(1) = (P(1) + P(2))/2 !Both centres are on the midpoint, but N = 1.
ELSE !Finally, the ordinary case.
N = 2 !Two circles.
MID = (P(1) + P(2))/2 !Midway between the two points.
D = SQRT((R/D)**2 - 1) !Rescale vector DP.
P = MID + DP*CMPLX(0,(/+D,-D/)) !Array (0,+D), (0,-D)
END IF !P(1) = DP*CMPLX(0,+D) and P(2) = DP*CMPLX(0,-D)
END SUBROUTINE BUBBLE !Careful! P and N are modified.
END MODULE GEOMETRY !Not much.
 
PROGRAM POKE !A tester.
USE GEOMETRY !Useful to I. Newton.
COMPLEX P(2) !A pair of points.
REAL PP(4) !Also a pair.
EQUIVALENCE (P,PP) !Since free-format input likes (x,y), not x,y
REAL R !This is not complex.
INTEGER MSG,IN !I/O unit numbers.
MSG = 6 !Standard output.
OPEN (MSG, RECL = 120) !For "formatted" files, this length is in characters.
IN = 10 !For the disc file holding the test data.
WRITE (MSG,1) !Announce.
1 FORMAT ("Given two points and a radius, find the centres "
1 "of circles of that radius passing through those points.")
 
OPEN (IN,FILE="Circle.csv", STATUS = "OLD", ACTION="READ") !Have data, will compute.
10 READ (IN,*,END = 20) PP,R !Get two points and a radius.
WRITE (MSG,*) !Set off.
WRITE (MSG,*) P,R !Show the input.
CALL BUBBLE(P,R,N) !Calculate.
WRITE (MSG,*) P(1:N),SQUAWK(N) !Show results.
GO TO 10 !Try it again.
 
20 CLOSE(IN) !Finihed with input.
END !Finished. </syntaxhighlight>
 
Results: little attempt has been made to present a fancy layout, "free-format" output does well enough. Notably, complex numbers are presented in brackets with a comma as ''(x,y)''; a FORMAT statement version would have to supply those decorations. Free-format input also expects such bracketing when reading complex numbers. The supplied data format however does ''not'' include the brackets and so is improper. Suitable data would be
<pre>
(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
</pre>
The free-format input style allows spaces, a comma (with or without spaces), and even a tab as delimiters between data, but does not allow implicit delimiters so a sequence such as 2017-12-29 (a standard date format) would be rejected. Because the style of the supplied data does not include the brackets, when complex numbers are read from such an input stream, they are taken to be real numbers only so that each real number is deemed a complex number of the form (x,0); in this case the second number would be taken as being the real part of the second complex number. A mess results.
 
By using the EQUIVALENCE statement, array PP can be read via the free-format protocol, and so the first four numbers will be placed in array PP, which just happens to be the same storage area as the array P of complex numbers. This of course means that should proper bracketed complex numbers be presented as input, a different mess results.
 
Output:
<pre>
Given two points and a radius, find the centres of circles of that radius passing through those points.
 
(0.1234000,0.9876000) (0.8765000,0.2345000) 2.000000
(1.863112,1.974212) (-0.8632119,-0.7521119) Two circles.
 
(0.0000000E+00,2.000000) (0.0000000E+00,0.0000000E+00) 1.000000
(0.0000000E+00,1.000000) One circle: points are 2R apart.
 
(0.1234000,0.9876000) (0.1234000,0.9876000) 2.000000
Innumerable circles: co-incident points, R > 0.
 
(0.1234000,0.9876000) (0.8765000,0.2345000) 0.5000000
No circles: points are more than 2R apart.
 
(0.1234000,0.9876000) (0.1234000,0.9876000) 0.0000000E+00
One 'circle', centred on the co-incident points. R is zero!
</pre>
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">Type Point
As Double x,y
Declare Property length As Double
End Type
 
Property point.length As Double
Return Sqr(x*x+y*y)
End Property
 
Sub circles(p1 As Point,p2 As Point,radius As Double)
Print "Points ";"("&p1.x;","&p1.y;"),("&p2.x;","&p2.y;")";", Rad ";radius
Var ctr=Type<Point>((p1.x+p2.x)/2,(p1.y+p2.y)/2)
Var half=Type<Point>(p1.x-ctr.x,p1.y-ctr.y)
Var lenhalf=half.length
If radius<lenhalf Then Print "Can't solve":Print:Exit Sub
If lenhalf=0 Then Print "Points are the same":Print:Exit Sub
Var dist=Sqr(radius^2-lenhalf^2)/lenhalf
Var rot= Type<Point>(-dist*(p1.y-ctr.y) +ctr.x,dist*(p1.x-ctr.x) +ctr.y)
Print " -> Circle 1 ("&rot.x;","&rot.y;")"
rot= Type<Point>(-(rot.x-ctr.x) +ctr.x,-((rot.y-ctr.y)) +ctr.y)
Print" -> Circle 2 ("&rot.x;","&rot.y;")"
Print
End Sub
 
 
Dim As Point p1=(.1234,.9876),p2=(.8765,.2345)
circles(p1,p2,2)
p1=Type<Point>(0,2):p2=Type<Point>(0,0)
circles(p1,p2,1)
p1=Type<Point>(.1234,.9876):p2=p1
circles(p1,p2,2)
p1=Type<Point>(.1234,.9876):p2=Type<Point>(.8765,.2345)
circles(p1,p2,.5)
p1=Type<Point>(.1234,.9876):p2=p1
circles(p1,p2,0)
 
Sleep</syntaxhighlight>
{{out}}
<pre>Points (0.1234,0.9876),(0.8765,0.2345), Rad 2
-> Circle 1 (-0.8632118016581893,-0.7521118016581889)
-> Circle 2 (1.863111801658189,1.974211801658189)
 
Points (0,2),(0,0), Rad 1
-> Circle 1 (0,1)
-> Circle 2 (0,1)
 
Points (0.1234,0.9876),(0.1234,0.9876), Rad 2
Points are the same
 
Points (0.1234,0.9876),(0.8765,0.2345), Rad 0.5
Can't solve
 
Points (0.1234,0.9876),(0.1234,0.9876), Rad 0
Points are the same</pre>
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 932 ⟶ 1,660:
fmt.Println()
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 964 ⟶ 1,692:
Center: {0.1234 0.9876}
</pre>
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">class Circles {
private static class Point {
private final double x, y
 
Point(Double x, Double y) {
this.x = x
this.y = y
}
 
double distanceFrom(Point other) {
double dx = x - other.x
double dy = y - other.y
return Math.sqrt(dx * dx + dy * dy)
}
 
@Override
boolean equals(Object other) {
//if (this == other) return true
if (other == null || getClass() != other.getClass()) return false
Point point = (Point) other
return x == point.x && y == point.y
}
 
@Override
String toString() {
return String.format("(%.4f, %.4f)", x, y)
}
}
 
private static Point[] findCircles(Point p1, Point p2, double r) {
if (r < 0.0) throw new IllegalArgumentException("the radius can't be negative")
if (r == 0.0.toDouble() && p1 != p2) throw new IllegalArgumentException("no circles can ever be drawn")
if (r == 0.0.toDouble()) return [p1, p1]
if (Objects.equals(p1, p2)) throw new IllegalArgumentException("an infinite number of circles can be drawn")
double distance = p1.distanceFrom(p2)
double diameter = 2.0 * r
if (distance > diameter) throw new IllegalArgumentException("the points are too far apart to draw a circle")
Point center = new Point((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0)
if (distance == diameter) return [center, center]
double mirrorDistance = Math.sqrt(r * r - distance * distance / 4.0)
double dx = (p2.x - p1.x) * mirrorDistance / distance
double dy = (p2.y - p1.y) * mirrorDistance / distance
return [
new Point(center.x - dy, center.y + dx),
new Point(center.x + dy, center.y - dx)
]
}
 
static void main(String[] args) {
Point[] p = [
new Point(0.1234, 0.9876),
new Point(0.8765, 0.2345),
new Point(0.0000, 2.0000),
new Point(0.0000, 0.0000)
]
Point[][] points = [
[p[0], p[1]],
[p[2], p[3]],
[p[0], p[0]],
[p[0], p[1]],
[p[0], p[0]],
]
double[] radii = [2.0, 1.0, 2.0, 0.5, 0.0]
for (int i = 0; i < radii.length; ++i) {
Point p1 = points[i][0]
Point p2 = points[i][1]
double r = radii[i]
printf("For points %s and %s with radius %f\n", p1, p2, r)
try {
Point[] circles = findCircles(p1, p2, r)
Point c1 = circles[0]
Point c2 = circles[1]
if (Objects.equals(c1, c2)) {
printf("there is just one circle with center at %s\n", c1)
} else {
printf("there are two circles with centers at %s and %s\n", c1, c2)
}
} catch (IllegalArgumentException ex) {
println(ex.getMessage())
}
println()
}
}
}</syntaxhighlight>
{{out}}
<pre>For points (0.1234, 0.9876) and (0.8765, 0.2345) with radius 2.000000
there are two circles with centers at (1.8631, 1.9742) and (-0.8632, -0.7521)
 
For points (0.0000, 2.0000) and (0.0000, 0.0000) with radius 1.000000
there is just one circle with center at (0.0000, 1.0000)
 
For points (0.1234, 0.9876) and (0.1234, 0.9876) with radius 2.000000
an infinite number of circles can be drawn
 
For points (0.1234, 0.9876) and (0.8765, 0.2345) with radius 0.500000
the points are too far apart to draw a circle
 
For points (0.1234, 0.9876) and (0.1234, 0.9876) with radius 0.000000
there is just one circle with center at (0.1234, 0.9876)</pre>
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">add (a, b) (x, y) = (a + x, b + y)
sub (a, b) (x, y) = (a - x, b - y)
magSqr (a, b) = (a ^^ 2) + (b ^^ 2)
Line 1,001 ⟶ 1,829:
((0.1234, 0.9876), (0.1234, 0.9876), 2),
((0.1234, 0.9876), (0.8765, 0.2345), 0.5),
((0.1234, 0.9876), (0.1234, 0.1234), 0)]</langsyntaxhighlight>
{{out}}
<pre>Just ((-0.8632118016581896,-0.7521118016581892),(1.8631118016581893,1.974211801658189))
Line 1,011 ⟶ 1,839:
{{trans|AutoHotKey}}
Works in both languages.
<langsyntaxhighlight lang="unicon">procedure main()
A := [ [0.1234, 0.9876, 0.8765, 0.2345, 2.0],
[0.0000, 2.0000, 0.0000, 0.0000, 1.0],
Line 1,032 ⟶ 1,860:
if d = r2 then return "Single circle at ("||cx1||","||cy1||")"
return "("||cx1||","||cy1||") and ("||cx2||","||cy2||")"
end</langsyntaxhighlight>
 
{{out}}
Line 1,044 ⟶ 1,872:
->
</pre>
 
=={{header|J}}==
 
2D computations are often easier using the complex plane.
<langsyntaxhighlight Jlang="j">average =: +/ % #
 
circles =: verb define"1
Line 1,092 ⟶ 1,919:
│0.1234 0.9876 0.1234 0.9876 0 │Degenerate point at 0.1234 0.9876 │
└───────────────────────────────┴────────────────────────────────────────────────────┘
</syntaxhighlight>
</lang>
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">import java.util.Objects;
 
public class Circles {
private static class Point {
private final double x, y;
 
public Point(Double x, Double y) {
this.x = x;
this.y = y;
}
 
public double distanceFrom(Point other) {
double dx = x - other.x;
double dy = y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
 
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
Point point = (Point) other;
return x == point.x && y == point.y;
}
 
@Override
public String toString() {
return String.format("(%.4f, %.4f)", x, y);
}
}
 
private static Point[] findCircles(Point p1, Point p2, double r) {
if (r < 0.0) throw new IllegalArgumentException("the radius can't be negative");
if (r == 0.0 && p1 != p2) throw new IllegalArgumentException("no circles can ever be drawn");
if (r == 0.0) return new Point[]{p1, p1};
if (Objects.equals(p1, p2)) throw new IllegalArgumentException("an infinite number of circles can be drawn");
double distance = p1.distanceFrom(p2);
double diameter = 2.0 * r;
if (distance > diameter) throw new IllegalArgumentException("the points are too far apart to draw a circle");
Point center = new Point((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0);
if (distance == diameter) return new Point[]{center, center};
double mirrorDistance = Math.sqrt(r * r - distance * distance / 4.0);
double dx = (p2.x - p1.x) * mirrorDistance / distance;
double dy = (p2.y - p1.y) * mirrorDistance / distance;
return new Point[]{
new Point(center.x - dy, center.y + dx),
new Point(center.x + dy, center.y - dx)
};
}
 
public static void main(String[] args) {
Point[] p = new Point[]{
new Point(0.1234, 0.9876),
new Point(0.8765, 0.2345),
new Point(0.0000, 2.0000),
new Point(0.0000, 0.0000)
};
Point[][] points = new Point[][]{
{p[0], p[1]},
{p[2], p[3]},
{p[0], p[0]},
{p[0], p[1]},
{p[0], p[0]},
};
double[] radii = new double[]{2.0, 1.0, 2.0, 0.5, 0.0};
for (int i = 0; i < radii.length; ++i) {
Point p1 = points[i][0];
Point p2 = points[i][1];
double r = radii[i];
System.out.printf("For points %s and %s with radius %f\n", p1, p2, r);
try {
Point[] circles = findCircles(p1, p2, r);
Point c1 = circles[0];
Point c2 = circles[1];
if (Objects.equals(c1, c2)) {
System.out.printf("there is just one circle with center at %s\n", c1);
} else {
System.out.printf("there are two circles with centers at %s and %s\n", c1, c2);
}
} catch (IllegalArgumentException ex) {
System.out.println(ex.getMessage());
}
System.out.println();
}
}
}</syntaxhighlight>
{{out}}
<pre>For points (0.1234, 0.9876) and (0.8765, 0.2345) with radius 2.000000
there are two circles with centers at (1.8631, 1.9742) and (-0.8632, -0.7521)
 
For points (0.0000, 2.0000) and (0.0000, 0.0000) with radius 1.000000
there is just one circle with center at (0.0000, 1.0000)
 
For points (0.1234, 0.9876) and (0.1234, 0.9876) with radius 2.000000
an infinite number of circles can be drawn
 
For points (0.1234, 0.9876) and (0.8765, 0.2345) with radius 0.500000
the points are too far apart to draw a circle
 
For points (0.1234, 0.9876) and (0.1234, 0.9876) with radius 0.000000
there is just one circle with center at (0.1234, 0.9876)</pre>
=={{header|JavaScript}}==
 
====ES6====
 
<langsyntaxhighlight JavaScriptlang="javascript">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 => [r*Math.cos(t) + p[0], r*Math.sin(t) + p[1]];
Line 1,141 ⟶ 2,069:
[[0.1234, 0.9876], [0.1234, 0.9876], 0.0]
].forEach((t,i) => console.log(`Test: ${i}: ${findC(...t)}`));
</langsyntaxhighlight>
 
Output:
<syntaxhighlight lang="javascript">
<lang JavaScript>
Test: 0: p1: 0.1234,0.9876, p2: 0.8765,0.2345, r:2 Result: Circle at 1.8631118016581891,1.974211801658189 Circle at -0.863211801658189,-0.7521118016581889
Test: 1: p1: 0,2, p2: 0,0, r:1 Result: Points on diameter. Circle at: 0,1
Line 1,150 ⟶ 2,078:
Test: 3: p1: 0.1234,0.9876, p2: 0.8765,0.2345, r:0.5 Result: No intersection. Points further apart than circle diameter
Test: 4: p1: 0.1234,0.9876, p2: 0.1234,0.9876, r:0 Result: Radius Zero
</syntaxhighlight>
</lang>
 
=={{header|jq}}==
{{works with|jq|1.4}}
In this section, a point in the plane will be represented by its Cartesian co-ordinates expressed as a JSON array: [x,y].
<langsyntaxhighlight lang="jq"># circle_centers is defined here as a filter.
# Input should be an array [x1, y1, x2, y2, r] giving the co-ordinates
# of the two points and a radius.
Line 1,181 ⟶ 2,108:
elif ($cx1 and $cy1 and $cx2 and $cy2) | not then "no solution"
else [$cx1, $cy1, $cx2, $cy2 ]
end;</langsyntaxhighlight>
'''Examples''':
<langsyntaxhighlight lang="jq">(
[0.1234, 0.9876, 0.8765, 0.2345, 2],
[0.0000, 2.0000, 0.0000, 0.0000, 1],
Line 1,190 ⟶ 2,117:
[0.1234, 0.9876, 0.1234, 0.9876, 0]
)
| "\(.) ───► \(circle_centers)"</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq -n -c -r -f /Users/peter/jq/circle_centers.jq
 
[0.1234,0.9876,0.8765,0.2345,2] ───► [1.8631118016581893,1.974211801658189,-0.8632118016581896,-0.7521118016581892]
Line 1,199 ⟶ 2,126:
[0.1234,0.9876,0.1234,0.9876,2] ───► infinitely many circles can be drawn
[0.1234,0.9876,0.8765,0.2345,0.5] ───► points are too far from each other
[0.1234,0.9876,0.1234,0.9876,0] ───► [0.1234,0.9876]</langsyntaxhighlight>
 
=={{header|Julia}}==
This solution uses the package [https://github.com/timholy/AffineTransforms.jl AffineTransforms.jl] to introduce a coordinate system (u, v) centered on the midpoint between the two points and rotated so that these points are on the u-axis. In this system, solving for the circles' centers is trivial. The two points are cast as complex numbers to aid in determining the location of the midpoint and rotation angle.
 
'''Types and Functions'''
<syntaxhighlight lang="julia">
<lang Julia>
immutable Point{T<:FloatingPoint}
x::T
Line 1,247 ⟶ 2,173:
return (cp, "Two Solutions")
end
</syntaxhighlight>
</lang>
 
'''Main'''
<syntaxhighlight lang="julia">
<lang Julia>
tp = [Point(0.1234, 0.9876),
Point(0.0000, 2.0000),
Line 1,278 ⟶ 2,204:
end
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,293 ⟶ 2,219:
(0.1234, 0.9876), 0.0000
</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.51
 
typealias IAE = IllegalArgumentException
Line 1,358 ⟶ 2,283:
println()
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,377 ⟶ 2,302:
there is just one circle with center at (0.1234, 0.9876)
</pre>
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
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
</syntaxhighlight>
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
'[RC] Circles of given radius through two points
for i = 1 to 5
Line 1,425 ⟶ 2,412:
 
end sub
</syntaxhighlight>
</lang>
 
Output:
<langsyntaxhighlight lang="text">
1) 0.1234 0.9876 0.8765 0.2345 2
(1.8631118,1.9742118)
Line 1,441 ⟶ 2,428:
5) 0.1234 0.9876 0.1234 0.9876 0
It will be a single point (0.1234,0.9876) of radius 0
</syntaxhighlight>
</lang>
=={{header|Lua}}==
{{trans|C}}
<syntaxhighlight lang="lua">function distance(p1, p2)
local dx = (p1.x-p2.x)
local dy = (p1.y-p2.y)
return math.sqrt(dx*dx + dy*dy)
end
 
function findCircles(p1, p2, radius)
local seperation = distance(p1, p2)
if seperation == 0.0 then
if radius == 0.0 then
print("No circles can be drawn through ("..p1.x..", "..p1.y..")")
else
print("Infinitely many circles can be drawn through ("..p1.x..", "..p1.y..")")
end
elseif seperation == 2*radius then
local cx = (p1.x+p2.x)/2
local cy = (p1.y+p2.y)/2
print("Given points are opposite ends of a diameter of the circle with center ("..cx..", "..cy..") and radius "..radius)
elseif seperation > 2*radius then
print("Given points are further away from each other than a diameter of a circle with radius "..radius)
else
local mirrorDistance = math.sqrt(math.pow(radius,2) - math.pow(seperation/2,2))
local dx = p2.x - p1.x
local dy = p1.y - p2.y
local ax = (p1.x + p2.x) / 2
local ay = (p1.y + p2.y) / 2
local mx = mirrorDistance * dx / seperation
local my = mirrorDistance * dy / seperation
c1 = {x=ax+my, y=ay+mx}
c2 = {x=ax-my, y=ay-mx}
 
print("Two circles are possible.")
print("Circle C1 with center ("..c1.x..", "..c1.y.."), radius "..radius)
print("Circle C2 with center ("..c2.x..", "..c2.y.."), radius "..radius)
end
print()
end
 
cases = {
{x=0.1234, y=0.9876}, {x=0.8765, y=0.2345},
{x=0.0000, y=2.0000}, {x=0.0000, y=0.0000},
{x=0.1234, y=0.9876}, {x=0.1234, y=0.9876},
{x=0.1234, y=0.9876}, {x=0.8765, y=0.2345},
{x=0.1234, y=0.9876}, {x=0.1234, y=0.9876}
}
radii = { 2.0, 1.0, 2.0, 0.5, 0.0 }
for i=1, #radii do
print("Case "..i)
findCircles(cases[i*2-1], cases[i*2], radii[i])
end</syntaxhighlight>
{{out}}
<pre>Case 1
Two circles are possible.
Circle C1 with center (1.8631118016582, 1.9742118016582), radius 2
Circle C2 with center (-0.86321180165819, -0.75211180165819), radius 2
 
Case 2
Given points are opposite ends of a diameter of the circle with center (0, 1) and radius 1
 
Case 3
Infinitely many circles can be drawn through (0.1234, 0.9876)
 
Case 4
Given points are further away from each other than a diameter of a circle with radius 0.5
 
Case 5
No circles can be drawn through (0.1234, 0.9876)</pre>
=={{header|Maple}}==
<langsyntaxhighlight lang="maple">drawCircles := proc(x1, y1, x2, y2, r, $)
local c1, c2, p1, p2;
use geometry in
Line 1,471 ⟶ 2,526:
drawCircles(0.1234, 0.9876, 0.1234, 0.9876, 2.0);
drawCircles(0.1234, 0.9876, 0.8765, 0.2345, 0.5);
drawCircles(0.1234, 0.9876, 0.1234, 0.9876, 0.0);</langsyntaxhighlight>
{{out}}
[[File:Circles1_Maple.png]]
Line 1,481 ⟶ 2,536:
The circle is a point at [.1234, .9876].
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
 
<syntaxhighlight lang="mathematica">Off[Solve::ratnz];
=={{header|Mathematica}}==
<lang Mathematica>Off[Solve::ratnz];
circs::invrad = "The radius is invalid.";
circs::equpts = "The given points (`1`, `2`) are equivalent.";
Line 1,498 ⟶ 2,552:
Values /@
Solve[Abs[x - p1x]^2 + Abs[y - p1y]^2 ==
Abs[x - p2x]^2 + Abs[y - p2y]^2 == r^2, {x, y}];</langsyntaxhighlight>
{{out}}
<pre>In[2]:= circs[{.1234, .9876}, {.8765, .2345}, 2.]
{{-0.863212, -0.752112}, {1.86311, 1.97421}}
 
Outcircs[2]= {{-0.8632121234, -0.7521129876}, {1.863111234, 1.97421}9876}, 2.]
 
In[3]:= circs[{.1234, .9876}, {.1234, .9876}, 2.]
 
circs::equpts: The given points (0.1234`, 0.9876`) are equivalent.
circs[{.1234, .9876}, {.8765, .2345}, .5]
 
In[4]circs::dist:= circs[{The given points (0.1234`, 0.9876},`) {and (0.8765`, 0.2345},`) are too far apart for radius 0.5]`.
circs[{.1234, .9876}, {.1234, .9876}, 0.]
 
circs::dist: The given points (0.1234`, 0.9876`) and (0.8765`, 0.2345`) are too
far apart for radius 0.5`.
 
In[5]:= circs[{.1234, .9876}, {.1234, .9876}, 0.]
 
circs::invrad: The radius is invalid.</pre>
 
=={{header|Maxima}}==
<langsyntaxhighlight Maximalang="maxima">/* define helper function */
vabs(a):= sqrt(a.a);
realp(e):=freeof(%i, e);
Line 1,560 ⟶ 2,605:
apply('getsol, cons(sol, d[2]));
apply('getsol, cons(sol, d[3]));
apply('getsol, cons(sol, d[4]));</langsyntaxhighlight>
{{out}}
<syntaxhighlight lang="text">apply('getsol, cons(sol, d[1]));
two solutions
(%o9) [[x0 = 1.86311180165819, y0 = 1.974211801658189],
Line 1,574 ⟶ 2,619:
(%i12) apply('getsol, cons(sol, d[4]));
infinity many solutions
(%o12) infmany</langsyntaxhighlight>
 
=={{header|МК-61/52}}==
<syntaxhighlight lang="text">П0 С/П П1 С/П П2 С/П П3 С/П П4
ИП2 ИП0 - x^2 ИП3 ИП1 - x^2 + КвКор П5
ИП0 ИП2 + 2 / П6 ИП1 ИП3 + 2 / П7
Line 1,588 ⟶ 2,632:
ИП4 2 * ИП5 - ПE x#0 97 ИПB ИПA 8 5 ИНВ С/П
ИПE x>=0 97 8 3 ИНВ С/П
ИПD ИПC ИПB ИПA С/П</langsyntaxhighlight>
 
{{in}}
Line 1,598 ⟶ 2,642:
"8.L" if the points are coincident; "8.-" if the points are opposite ends of a diameter of the circle, РY and РZ are coordinates of the center; "8.Г" if the points are farther away from each other than a diameter of a circle; else РX, РY and РZ, РT are coordinates of the circles centers.
</pre>
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE Circles;
FROM EXCEPTIONS IMPORT AllocateSource,ExceptionSource,GetMessage,RAISE;
FROM FormatString IMPORT FormatString;
FROM LongMath IMPORT sqrt;
FROM LongStr IMPORT RealToStr;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
 
VAR
TextWinExSrc : ExceptionSource;
 
TYPE
Point = RECORD
x,y : LONGREAL;
END;
Pair = RECORD
a,b : Point;
END;
 
PROCEDURE Distance(p1,p2 : Point) : LONGREAL;
VAR dx,dy : LONGREAL;
BEGIN
dx := p1.x - p2.x;
dy := p1.y - p2.y;
RETURN sqrt(dx*dx + dy*dy)
END Distance;
 
PROCEDURE Equal(p1,p2 : Point) : BOOLEAN;
BEGIN
RETURN (p1.x=p2.x) AND (p1.y=p2.y)
END Equal;
 
PROCEDURE WritePoint(p : Point);
VAR buf : ARRAY[0..63] OF CHAR;
BEGIN
WriteString("(");
RealToStr(p.x, buf);
WriteString(buf);
WriteString(", ");
RealToStr(p.y, buf);
WriteString(buf);
WriteString(")");
END WritePoint;
 
PROCEDURE FindCircles(p1,p2 : Point; r : LONGREAL) : Pair;
VAR
distance,diameter,mirrorDistance,dx,dy : LONGREAL;
center : Point;
BEGIN
IF r < 0.0 THEN RAISE(TextWinExSrc, 0, "the radius can't be negative") END;
IF (r = 0.0) AND NOT Equal(p1,p2) THEN RAISE(TextWinExSrc, 0, "No circles can ever be drawn") END;
IF r = 0.0 THEN RETURN Pair{p1,p1} END;
IF Equal(p1,p2) THEN RAISE(TextWinExSrc, 0, "an infinite number of circles can be drawn") END;
distance := Distance(p1,p2);
diameter := 2.0 * r;
IF distance > diameter THEN RAISE(TextWinExSrc, 0, "the points are too far apart to draw a circle") END;
center := Point{(p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0};
IF distance = diameter THEN RETURN Pair{center, center} END;
mirrorDistance := sqrt(r * r - distance * distance / 4.0);
dx := (p2.x - p1.x) * mirrorDistance / distance;
dy := (p2.y - p1.y) * mirrorDistance / distance;
RETURN Pair{
{center.x - dy, center.y + dx},
{center.x + dy, center.y - dx}
}
END FindCircles;
 
PROCEDURE Print(p1,p2 : Point; r : LONGREAL) : BOOLEAN;
VAR
buf : ARRAY[0..63] OF CHAR;
result : Pair;
BEGIN
WriteString("For points ");
WritePoint(p1);
WriteString(" and ");
WritePoint(p2);
WriteString(" with radius ");
RealToStr(r, buf);
WriteString(buf);
WriteLn;
 
result := FindCircles(p1,p2,r);
IF Equal(result.a, result.b) THEN
WriteString("there is just one circle with the center at ");
WritePoint(result.a);
WriteLn;
ELSE
WriteString("there are two circles with centers at ");
WritePoint(result.a);
WriteString(" and ");
WritePoint(result.b);
WriteLn;
END;
WriteLn;
RETURN TRUE
EXCEPT
GetMessage(buf);
WriteString(buf);
WriteLn;
WriteLn;
RETURN FALSE
END Print;
 
VAR p0,p1,p2,p3 : Point;
BEGIN
AllocateSource(TextWinExSrc);
p0 := Point{0.1234,0.9876};
p1 := Point{0.8765,0.2345};
p2 := Point{0.0000,2.0000};
p3 := Point{0.0000,0.0000};
 
Print(p0,p1,2.0);
Print(p2,p3,1.0);
Print(p0,p0,2.0);
Print(p0,p1,0.5);
Print(p0,p0,0.0);
 
ReadChar
END Circles.</syntaxhighlight>
=={{header|Nim}}==
{{trans|Python}}
<langsyntaxhighlight lang="nim">import math
 
type
Line 1,608 ⟶ 2,770:
 
proc circles(p1, p2: Point, r: float): tuple[c1, c2: Circle] =
if r == 0: raise newException(EInvalidValueValueError,
"radius of zero")
if p1 == p2: raise newException(EInvalidValueValueError,
"coincident points gives infinite number of Circles")
 
Line 1,617 ⟶ 2,779:
# dist between points
let q = sqrt(dx*dx + dy*dy)
if q > 2.0*r: raise newException(EInvalidValueValueError,
"separation of points > diameter")
 
Line 1,646 ⟶ 2,808:
echo " ", c1
echo " ", c2
except EInvalidValueValueError:
echo " ERROR: ", getCurrentExceptionMsg()
echo ""</langsyntaxhighlight>
{{out}}
<pre>Through points:
Line 1,686 ⟶ 2,848:
You can construct the following circles:
ERROR: radius of zero</pre>
=={{header|OCaml}}==
Original version by [http://rosettacode.org/wiki/User:Vanyamil User:Vanyamil]
<syntaxhighlight lang="ocaml">
(* Task : Circles of given radius through two points *)
 
(* Types to make code even more readable *)
type point = float * float
type radius = float
type circle = Circle of radius * point
type circ_output =
NoSolution
| OneSolution of circle
| TwoSolutions of circle * circle
| InfiniteSolutions
;;
 
(* Actual function *)
let circles_2points_radius (x1, y1 : point) (x2, y2 : point) (r : radius) =
let (dx, dy) = (x2 -. x1, y2 -. y1) in
let dist_sq = dx *. dx +. dy *. dy in
match dist_sq, r with
(* Edge case - point circles *)
| 0., 0. -> OneSolution (Circle (r, (x1, y1)))
(* Edge case - coinciding points *)
| 0., _ -> InfiniteSolutions
| _ ->
let side_len_sq = r *. r -. dist_sq /. 4. in
let midp = ((x1 +. x2) *. 0.5, (y1 +. y2) *. 0.5) in
(* Points are too far apart; same whether r = 0 or not *)
if side_len_sq < 0. then NoSolution
(* Points are on diameter *)
else if side_len_sq = 0. then OneSolution (Circle (r, midp))
else
(* A right-angle triangle is made with the radius as hyp, dist/2 as one side *)
let side_len = sqrt (r *. r -. dist_sq /. 4.) in
let dist = sqrt dist_sq in
(* A 90-deg rotation of a vector (x, y) is obtained by either (y, -x) or (-y, x)
We need both, so pick one and the other is its negative.
*)
let (vx, vy) = (-. dy *. side_len /. dist, dx *. side_len /. dist) in
let c1 = Circle (r, (fst midp +. vx, snd midp +. vy)) in
let c2 = Circle (r, (fst midp -. vx, snd midp -. vy)) in
TwoSolutions (c1, c2)
;;
 
(* Relevant tests and printing *)
let tests = [
(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;
] ;;
 
let format_output (out : circ_output) = match out with
| NoSolution -> print_endline "No solution"
| OneSolution (Circle (_, (x, y))) -> Printf.printf "One solution: (%.6f, %.6f)\n" x y
| TwoSolutions (Circle (_, (x1, y1)), Circle (_, (x2, y2))) ->
Printf.printf "Two solutions: (%.6f, %.6f) and (%.6f, %.6f)\n" x1 y1 x2 y2
| InfiniteSolutions -> print_endline "Infinite solutions"
;;
 
let _ =
List.iter
(fun (a, b, c) -> circles_2points_radius a b c |> format_output)
tests
;;
</syntaxhighlight>
{{out}}
<pre>
Two solutions: (1.863112, 1.974212) and (-0.863212, -0.752112)
One solution: (0.000000, 1.000000)
Infinite solutions
No solution
One solution: (0.123400, 0.987600)
</pre>
=={{header|Oforth}}==
 
<langsyntaxhighlight lang="oforth">: circleCenter(x1, y1, x2, y2, r)
| d xmid ymid r1 md |
x2 x1 - sq y2 y1 - sq + sqrt -> d
Line 1,704 ⟶ 2,941:
System.Out "C1 : (" << xmid y1 y2 - md * d / + << ", " << ymid x2 x1 - md * d / + << ")" << cr
System.Out "C2 : (" << xmid y1 y2 - md * d / - << ", " << ymid x2 x1 - md * d / - << ")" << cr
;</langsyntaxhighlight>
 
{{out}}
Line 1,725 ⟶ 2,962:
 
</pre>
 
=={{header|ooRexx}}==
{{trans|REXX}}
<langsyntaxhighlight lang="oorexx">/*REXX pgm finds 2 circles with a specific radius given two (X,Y) points*/
a.=''
a.1=0.1234 0.9876 0.8765 0.2345 2
Line 1,766 ⟶ 3,002:
f: Return format(arg(1),2,4) /* format a number with 4 dec dig.*/
 
::requires 'rxMath' library</langsyntaxhighlight>
{{out}}
<pre> x1 y1 x2 y2 radius cir1x cir1y cir2x cir2y
Line 1,775 ⟶ 3,011:
0.1234 0.9876 0.8765 0.2345 0.5 points are too far apart for the given radius
0.1234 0.9876 0.1234 0.9876 0.0 radius of zero gives no circles.</pre>
=={{header|OpenSCAD}}==
<syntaxhighlight lang="OpenSCAD">
// distance between two points
function distance(p1, p2) = sqrt((difference(p2.x, p1.x)) ^ 2 + (difference(p2.y, p1.y) ^ 2));
// difference between two values in any order
function difference(a, b) = let(x = a > b ? a - b : b - a) x;
 
// function to find the circles of given radius through two points
function circles_of_given_radius_through_two_points(p1, p2, radius) =
let(mid = (p1 + p2)/2, q = distance(p1, p2), x_dist = sqrt(radius ^ 2 - (q / 2) ^ 2) * (p1.y - p2.y) / q,
y_dist = sqrt(radius ^ 2 - (q / 2) ^ 2) * (p2.x - p1.x) / q)
// point 1 and point 2 must not be the same point
assert(p1 != p2)
// radius must be more than 0
assert(radius > 0)
// distance between points cannot be more than diameter
assert(q < radius * 2)
// return both qualifying centres
[mid + [ x_dist, y_dist ], mid - [ x_dist, y_dist ]];
 
// test module for circles_of_given_radius_through_two_points
module test_circles_of_given_radius_through_two_points()
{
tests = [
[ [ -10, -10, 0 ], [ 50, 0, 0 ], 100 ], [ [ 200, 0, 0 ], [ 220, -20, 0 ], 30 ],
[ [ 300, 100, 0 ], [ 350, 200, 0 ], 80 ]
];
 
for (t = tests)
{
let(start = t[0], end = t[1], radius = t[2])
{
// plot start and end dots - these should be at the intersections of the circles
color("green") translate(start) cylinder(h = 3, r = 4);
color("green") translate(end) cylinder(h = 3, r = 4);
 
// call function
centres = circles_of_given_radius_through_two_points(start, end, radius);
echo("centres", centres);
// plot results
color("yellow") translate(centres[0]) cylinder(h = 1, r = radius);
color("red") translate(centres[1]) cylinder(h = 2, r = radius);
};
};
// The following tests will stop all execution. To run them, uncomment one at a time
// should fail - same points
// echo(circles_of_given_radius_through_two_points([0,0],[0,0],1));
// should fail - points are more than diameter apart
// echo(circles_of_given_radius_through_two_points(p1 = [0,0], p2 = [0,101], radius = 50));
// should fail - radius must be greater than 0
// echo(circles_of_given_radius_through_two_points(p1= [1,1], p2 = [10,1], radius = 0));
}
 
test_circles_of_given_radius_through_two_points();
</syntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">circ(a, b, r)={
if(a==b, return("impossible"));
my(h=(b-a)/2,t=sqrt(r^2-abs(h)^2)/abs(h)*h);
Line 1,786 ⟶ 3,077:
circ(0.1234 + 0.9876*I, 0.1234 + 0.9876*I, 2)
circ(0.1234 + 0.9876*I, 0.8765 + 0.2345*I, .5)
circ(0.1234 + 0.9876*I, 0.1234 + 0.9876*I, 0)</langsyntaxhighlight>
{{out}}
<pre>%1 = [1.86311180 + 1.97421180*I, -0.863211802 - 0.752111802*I]
Line 1,793 ⟶ 3,084:
%4 = [0.370374144 + 0.740625856*I, 0.629525856 + 0.481474144*I]
%5 = "impossible"</pre>
 
 
=={{header|Perl}}==
{{trans|Python}}
<syntaxhighlight lang="perl">use strict;
<lang perl>
 
sub circles {
use feature 'say';
sub circles_from_p1p2r {
my ($x1, $y1, $x2, $y2, $r) = @_;
 
die 'Radius is zero' if $r == 0.0;
return "Radius is zero" if $r == 0;
die 'coincident points gives infinite number of Circles' if $x1 == $x2 && $y1 == $y2;
return "Coincident points gives infinite number of circles" if $x1 == $x2 and $y1 == $y2;
 
# delta x, delta y between points
my ($dx, $dy) = ($x2 - $x1, $y2 - $y1);
my $q = sqrt($dx**2 + $dy**2);
diereturn 'separation"Separation of points >greater than diameter'" if $q > 2.0*$r;
 
# halfway point
my ($x3, $y3) = (($x1 + $x2) / 2, ($y1 + $y2) / 2);
# distance along the mirror line
my $d = sqrt($r**2-($q/2)**2);
# One answer
my @c1 = ($x3 - $d*$dy/$q, $y3 + $d*$dx/$q, $r);
# The other answer
my @c2 = ($x3 + $d*$dy/$q, $y3 - $d*$dx/$q, $r);
return (@c1, @c2);
}
 
# pair of solutions
my @arr = ([0.1234, 0.9876, 0.8765, 0.2345, 2.0],
[0 sprintf '(%.00004f, 2%.0000,4f) 0.0000,and 0(%.00004f, 1%.0]4f)',
$x3 - $d*$dy/$q, $y3 + $d*$dx/$q,
# [0.1234, 0.9876, 0.1234, 0.9876, 2.0],
$x3 + $d*$dy/$q, $y3 - $d*$dx/$q;
# [0.1234, 0.9876, 0.8765, 0.2345, 0.5],
# [0.1234, 0.9876, 0.1234, 0.9876, 0.0]
);
for(@arr) {
my @res = circles_from_p1p2r @{$_};
say "@res";
}
 
my @arr = (
</lang>
[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]
);
 
printf "(%.4f, %.4f) and (%.4f, %.4f) with radius %.1f: %s\n", @$_[0..4], circles @$_ for @arr;</syntaxhighlight>
=={{header|Perl 6}}==
<lang Perl6>multi sub circles (@A, @B where ([and] @A Z== @B), 0.0) { 'Degenerate point' }
multi sub circles (@A, @B where ([and] @A Z== @B), $) { 'Infinitely many share a point' }
multi sub circles (@A, @B, $radius) {
my @middle = (@A Z+ @B) X/ 2;
my @diff = @A Z- @B;
my $q = sqrt [+] @diff X** 2;
return 'Too far apart' if $q > $radius * 2;
 
my @orth = -@diff[0], @diff[1] X* sqrt($radius ** 2 - ($q / 2) ** 2) / $q;
return (@middle Z+ @orth), (@middle Z- @orth);
}
 
my @input =
([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),
;
 
for @input {
say .list.perl, ': ', circles(|$_).join(' and ');
}</lang>
{{out}}
<pre>([0.1234, 0.9876],) and [(0.8765, 0.2345],) with radius 2.0): (1.863111801658198631, 1.974211801658199742) and (-0.8632118016581898632, -0.7521118016581897521)
([0.00000, 2.0],0000) and [(0.00000, 0.0],0000) with radius 1.0): (0.0000, 1.0000) and (0.0000, 1.0000)
([0.1234, 0.9876],) and [(0.1234, 0.9876],) with radius 2.0): InfinitelyCoincident points gives manyinfinite sharenumber aof pointcircles
([0.1234, 0.9876],) and [(0.8765, 0.2345],) with radius 0.5): TooSeparation of points greater farthan apartdiameter
([0.1234, 0.9876],) and [(0.1234, 0.9876],) with radius 0.0): DegenerateRadius is pointzero</pre>
=={{header|Phix}}==
 
<!--<syntaxhighlight lang="phix">(phixonline)-->
Another possibility is to use the Complex plane,
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
for it often makes calculations easier with plane geometry:
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">0.1234</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9876</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.8765</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.2345</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.0</span><span style="color: #0000FF;">},</span>
 
<span style="color: #0000FF;">{</span><span style="color: #000000;">0.0000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.0000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0</span><span style="color: #0000FF;">},</span>
<lang perl6>multi sub circles ($a, $b where $a == $b, 0.0) { 'Degenerate point' }
<span style="color: #0000FF;">{</span><span style="color: #000000;">0.1234</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9876</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.1234</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9876</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.0</span><span style="color: #0000FF;">},</span>
multi sub circles ($a, $b where $a == $b, $) { 'Infinitely many share a point' }
<span style="color: #0000FF;">{</span><span style="color: #000000;">0.1234</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9876</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.8765</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.2345</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.5</span><span style="color: #0000FF;">},</span>
multi sub circles ($a, $b, $r) {
<span style="color: #0000FF;">{</span><span style="color: #000000;">0.1234</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9876</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.1234</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9876</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0</span><span style="color: #0000FF;">}}</span>
my $h = ($b - $a) / 2;
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
my $l = sqrt($r**2 - $h.abs**2);
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
return 'Too far apart' if $l.isNaN;
<span style="color: #000000;">xd</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">yd</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span>
return map { $a + $h + $l * $_ * $h / $h.abs }, i, -i;
<span style="color: #000000;">s2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xd</span><span style="color: #0000FF;">*</span><span style="color: #000000;">xd</span><span style="color: #0000FF;">+</span><span style="color: #000000;">yd</span><span style="color: #0000FF;">*</span><span style="color: #000000;">yd</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">sep</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">),</span>
}
<span style="color: #000000;">xh</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">yh</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span>
 
<span style="color: #004080;">string</span> <span style="color: #000000;">txt</span>
my @input =
<span style="color: #008080;">if</span> <span style="color: #000000;">sep</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
(0.1234 + 0.9876i, 0.8765 + 0.2345i, 2.0),
<span style="color: #000000;">txt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"same points/"</span><span style="color: #0000FF;">&</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"radius is zero"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"infinite solutions"</span><span style="color: #0000FF;">)</span>
(0.0000 + 2.0000i, 0.0000 + 0.0000i, 1.0),
<span style="color: #008080;">elsif</span> <span style="color: #000000;">sep</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">r</span> <span style="color: #008080;">then</span>
(0.1234 + 0.9876i, 0.1234 + 0.9876i, 2.0),
<span style="color: #000000;">txt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"opposite ends of diameter with centre {%.4f,%.4f}"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">xh</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yh</span><span style="color: #0000FF;">})</span>
(0.1234 + 0.9876i, 0.8765 + 0.2345i, 0.5),
<span style="color: #008080;">elsif</span> <span style="color: #000000;">sep</span><span style="color: #0000FF;">></span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">r</span> <span style="color: #008080;">then</span>
(0.1234 + 0.9876i, 0.1234 + 0.9876i, 0.0),
<span style="color: #000000;">txt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"too far apart (%.4f &gt; %.4f)"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">sep</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">r</span><span style="color: #0000FF;">})</span>
;
<span style="color: #008080;">else</span>
 
<span style="color: #004080;">atom</span> <span style="color: #000000;">md</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">*</span><span style="color: #000000;">r</span><span style="color: #0000FF;">-</span><span style="color: #000000;">s2</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">xs</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">md</span><span style="color: #0000FF;">*</span><span style="color: #000000;">xd</span><span style="color: #0000FF;">/</span><span style="color: #000000;">sep</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ys</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">md</span><span style="color: #0000FF;">*</span><span style="color: #000000;">yd</span><span style="color: #0000FF;">/</span><span style="color: #000000;">sep</span>
for @input {
<span style="color: #000000;">txt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"{%.4f,%.4f} and {%.4f,%.4f}"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">xh</span><span style="color: #0000FF;">+</span><span style="color: #000000;">ys</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yh</span><span style="color: #0000FF;">+</span><span style="color: #000000;">xs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xh</span><span style="color: #0000FF;">-</span><span style="color: #000000;">ys</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yh</span><span style="color: #0000FF;">-</span><span style="color: #000000;">xs</span><span style="color: #0000FF;">})</span>
say .join(', '), ': ', circles(|$_).join(' and ');
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
}</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"points {%.4f,%.4f}, {%.4f,%.4f} with radius %.1f ==&gt; %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">txt</span><span style="color: #0000FF;">})</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
<pre>0.1234+0.9876i, 0.8765+0.2345i, 2: 1.86311180165819+1.97421180165819i and -0.863211801658189-0.752111801658189i
points {0.1234,0.9876}, {0.8765,0.2345} with radius 2.0 ==> {1.8631,1.9742} and {-0.8632,-0.7521}
0+2i, 0+0i, 1: 0+1i and 0+1i
points {0.0000,2.0000}, {0.0000,0.0000} with radius 1.0 ==> opposite ends of diameter with centre {0.0000,1.0000}
0.1234+0.9876i, 0.1234+0.9876i, 2: Infinitely many share a point
points {0.1234+,0.9876i9876}, {0.8765+1234,0.2345i,9876} 0with radius 2.5:0 ==> Toosame farpoints/infinite apartsolutions
points {0.1234,0.9876}, {0.8765,0.2345} with radius 0.5 ==> too far apart (1.0650 > 1.0000)
0.1234+0.9876i, 0.1234+0.9876i, 0: Degenerate point</pre>
points {0.1234,0.9876}, {0.1234,0.9876} with radius 0.0 ==> same points/radius is zero
 
</pre>
=={{header|PL/I}}==
{{trans|REXX}}
<langsyntaxhighlight PLlang="pl/Ii">twoci: Proc Options(main);
Dcl 1 *(5),
2 m1x Dec Float Init(0.1234, 0,0.1234,0.1234,0.1234),
Line 1,937 ⟶ 3,204:
Return(res);
End;
End;</langsyntaxhighlight>
{{out}}
<pre> x1 y1 x2 y2 r cir1x cir1y cir2x cir2y
Line 1,947 ⟶ 3,214:
0.1234 0.9876 0.1234 0.9876 0 radius of zero gives no circles.
</pre>
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">DataSection
DataStart:
Data.d 0.1234, 0.9876, 0.8765, 0.2345, 2.0
Data.d 0.0000, 2.0000, 0.0000, 0.0000, 1.0
Data.d 0.1234, 0.9876, 0.1234, 0.9876, 2.0
Data.d 0.1234, 0.9876, 0.9765, 0.2345, 0.5
Data.d 0.1234, 0.9876, 0.1234, 0.9876, 0.0
DataEnd:
EndDataSection
Macro MaxRec : (?DataEnd-?DataStart)/SizeOf(P2r)-1 : EndMacro
 
Structure Pxy : x.d : y.d : EndStructure
Structure P2r : p1.Pxy : p2.Pxy : r.d : EndStructure
Structure PData : Prec.P2r[5] : EndStructure
 
Procedure.s cCenter(Rec.i)
If Rec<0 Or Rec>MaxRec : ProcedureReturn "Data set number incorrect." : EndIf
*myP.PData=?DataStart
r.d=*myP\Prec[Rec]\r
If r<=0.0 : ProcedureReturn "Illegal radius." : EndIf
r2.d=2.0*r
x1.d=*myP\Prec[Rec]\p1\x : x2.d=*myP\Prec[Rec]\p2\x
y1.d=*myP\Prec[Rec]\p1\y : y2.d=*myP\Prec[Rec]\p2\y
d.d=Sqr(Pow(x2-x1,2)+Pow(y2-y1,2))
If d=0.0 : ProcedureReturn "Identical points, infinite number of circles." : EndIf
If d>r2 : ProcedureReturn "No circles possible." : EndIf
z.d=Sqr(Pow(r,2)-Pow(d/2.0,2))
x3.d =(x1+x2)/2.0 : y3.d =(y1+y2)/2.0
cx1.d=x3+z*(y1-y2)/d : cy1.d=y3+z*(x2-x1)/d
cx2.d=x3-z*(y1-y2)/d : cy2.d=y3-z*(x2-x1)/d
If d=r2 : ProcedureReturn "Single circle at ("+StrD(cx1)+","+StrD(cy1)+")" : EndIf
ProcedureReturn "("+StrD(cx1)+","+StrD(cy1)+") and ("+StrD(cx2)+","+StrD(cy2)+")"
EndProcedure
 
If OpenConsole("")
For i=0 To MaxRec : PrintN(cCenter(i)) : Next : Input()
EndIf</syntaxhighlight>
{{out}}
<pre>(1.8631118017,1.9742118017) and (-0.8632118017,-0.7521118017)
Single circle at (0,1)
Identical points, infinite number of circles.
No circles possible.
Illegal radius.</pre>
=={{header|Python}}==
The function raises the ValueError exception for the special cases
and uses try - except to catch these and extract the exception detail.
 
<langsyntaxhighlight lang="python">from collections import namedtuple
from math import sqrt
 
Line 1,996 ⟶ 3,306:
print(' %r\n %r\n' % circles_from_p1p2r(p1, p2, r))
except ValueError as v:
print(' ERROR: %s\n' % (v.args[0],))</langsyntaxhighlight>
 
{{out}}
Line 2,035 ⟶ 3,345:
You can construct the following circles:
ERROR: radius of zero</pre>
 
 
=={{header|Racket}}==
Using library `plot/utils` for simple vector operations.
 
<langsyntaxhighlight lang="racket">
#lang racket
(require plot/utils)
Line 2,065 ⟶ 3,373:
;; returns a vector which is orthogonal to the geven one
(define orth (match-lambda [(vector x y) (vector y (- x))]))
</syntaxhighlight>
</lang>
 
{{out|Testing}}
Line 2,089 ⟶ 3,397:
Drawing circles:
 
<langsyntaxhighlight lang="racket">
(require 2htdp/image)
 
Line 2,105 ⟶ 3,413:
((compose (point p1) (point p2) (circ x1 r) (circ x2 r))
(empty-scene 100 100))
</syntaxhighlight>
</lang>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2020.08.1}}
<syntaxhighlight lang="raku" line>multi sub circles (@A, @B where ([and] @A Z== @B), 0.0) { 'Degenerate point' }
multi sub circles (@A, @B where ([and] @A Z== @B), $) { 'Infinitely many share a point' }
multi sub circles (@A, @B, $radius) {
my @middle = (@A Z+ @B) X/ 2;
my @diff = @A Z- @B;
my $q = sqrt [+] @diff X** 2;
return 'Too far apart' if $q > $radius * 2;
 
my @orth = -@diff[0], @diff[1] X* sqrt($radius ** 2 - ($q / 2) ** 2) / $q;
return (@middle Z+ @orth), (@middle Z- @orth);
}
 
my @input =
([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),
;
 
for @input {
say .list.raku, ': ', circles(|$_).join(' and ');
}</syntaxhighlight>
{{out}}
<pre>([0.1234, 0.9876], [0.8765, 0.2345], 2.0): 1.86311180165819 1.97421180165819 and -0.863211801658189 -0.752111801658189
([0.0, 2.0], [0.0, 0.0], 1.0): 0 1 and 0 1
([0.1234, 0.9876], [0.1234, 0.9876], 2.0): Infinitely many share a point
([0.1234, 0.9876], [0.8765, 0.2345], 0.5): Too far apart
([0.1234, 0.9876], [0.1234, 0.9876], 0.0): Degenerate point</pre>
 
Another possibility is to use the Complex plane,
for it often makes calculations easier with plane geometry:
 
<syntaxhighlight lang="raku" line>multi sub circles ($a, $b where $a == $b, 0.0) { 'Degenerate point' }
multi sub circles ($a, $b where $a == $b, $) { 'Infinitely many share a point' }
multi sub circles ($a, $b, $r) {
my $h = ($b - $a) / 2;
my $l = sqrt($r**2 - $h.abs**2);
return 'Too far apart' if $l.isNaN;
return map { $a + $h + $l * $_ * $h / $h.abs }, i, -i;
}
 
my @input =
(0.1234 + 0.9876i, 0.8765 + 0.2345i, 2.0),
(0.0000 + 2.0000i, 0.0000 + 0.0000i, 1.0),
(0.1234 + 0.9876i, 0.1234 + 0.9876i, 2.0),
(0.1234 + 0.9876i, 0.8765 + 0.2345i, 0.5),
(0.1234 + 0.9876i, 0.1234 + 0.9876i, 0.0),
;
 
for @input {
say .join(', '), ': ', circles(|$_).join(' and ');
}</syntaxhighlight>
 
{{out}}
<pre>0.1234+0.9876i, 0.8765+0.2345i, 2: 1.86311180165819+1.97421180165819i and -0.863211801658189-0.752111801658189i
0+2i, 0+0i, 1: 0+1i and 0+1i
0.1234+0.9876i, 0.1234+0.9876i, 2: Infinitely many share a point
0.1234+0.9876i, 0.8765+0.2345i, 0.5: Too far apart
0.1234+0.9876i, 0.1234+0.9876i, 0: Degenerate point</pre>
=={{header|REXX}}==
{{trans|XPL0}}
 
<br>The REXX language doesn't have a &nbsp; '''sqrt''' &nbsp; function, &nbsp; so one is included below.
<langsyntaxhighlight lang="rexx">/*REXX programpgm finds two2 circles with a specific radius given two2 (XX1,YY1) and points. (X2,Y2) ctr points*/
@.=; @.1= 0.1234 0.9876 0.8765 0.2345 2
@.2= 0 2 0 0 1
Line 2,119 ⟶ 3,490:
say ' ════════ ════════ ════════ ════════ ══════ ════════ ════════ ════════ ════════'
do j=1 while @.j\==''; parse var @.j p1 p2 p3 p4 r /*points, radii*/
say ffmt(p1) ffmt(p2) ffmt(p3) ffmt(p4) center(r/1, 9) "───► " 2circ(@.j)
end /*j*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
2circ: procedure; parse arg px py qx qy r .; x= (qx-px)/2; y= (qy-py)/2
bx= px + x; by=py+y; pb by=sqrt(x**2 py + y**2)
pb= sqrt(x**2 + y**2)
if r = 0 then return 'radius of zero yields no circles.'
if pb==0 then return 'coincident points give infinite circles.'
if pb >r then return 'points are too far apart for the specified radius.'
cb= sqrt(r**2 - pb**2); x1= y * cb / pb; x1=y*cb/pb; y1= x * cb / pb
return ffmt(bx-x1) ffmt(by+y1) ffmt(bx+x1) ffmt(by-y1)
/*──────────────────────────────────────────────────────────────────────────────────────*/
ffmt: arg f; f= right( format(arg(1)f, , 4), 9); _= f /*format the # with four4 decimaldec digits*/
if pos(.,f)\=>0 & pos('E',f)=0 then f= strip(f,'T',0) /*strip trailing 0s if decimal point.& ¬E*/
return left( strip(f, 'T', .), length(_) ) /*maybe strip trailing decimaldec point. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; arg x; if x=0 then return 0; d=digits(); numeric digits; h=d+6; m.=9
numeric form; parse value format(x,2,1,,0) 'E0' with g "E" _ .; g=g *.5'e'_ % 2
do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
return g</lang>
'''output'''
<pre>
x1 y1 x2 y2 radius circle1x circle1y circle2x circle2y
Line 2,150 ⟶ 3,521:
0.1234 0.9876 0.1234 0.9876 0 ───► radius of zero gives no circles.
</pre>
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Circles of given radius through two points
 
decimals(4)
x1 = 0.1234
y1 = 0.9876
x2 = 0.8765
y2 = 0.2345
r = 2.0
see "1 : " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + r + nl
twocircles(x1, y1, x2, y2, r)
 
x1 = 0.0000
y1 = 2.0000
x2 = 0.0000
y2 = 0.0000
r = 1.0
see "2 : " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + r + nl
twocircles(x1, y1, x2, y2, r)
 
x1 = 0.1234
y1 = 0.9876
x2 = 0.1234
y2 = 0.9876
r = 2.0
see "3 : " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + r + nl
twocircles(x1, y1, x2, y2, r)
 
x1 = 0.1234
y1 = 0.9876
x2 = 0.8765
y2 = 0.2345
r = 0.5
see "4 : " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + r + nl
twocircles(x1, y1, x2, y2, r)
 
x1 = 0.1234
y1 = 0.9876
x2 = 0.1234
y2 = 0.9876
r= 0.0
see "5 : " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + r + nl
twocircles(x1, y1, x2, y2, r)
func twocircles(x1, y1, x2, y2, r)
if x1=x2 and y1=y2
if r=0
see "It will be a single point (" + x1 + "," + y1 + ") of radius 0" + nl + nl
return
else
see "There are any number of circles via single point (" + x1 + "," + y1 + ") of radius " + r + nl + nl
return
ok
ok
r2 = sqrt(pow((x1-x2),2)+pow((y1-y2),2))/2
if r<r2
see "Points are too far apart (" + 2*r2 + ") - there are no circles of radius " + r + nl + nl
return
ok
cx=(x1+x2)/2
cy=(y1+y2)/2
dd2=sqrt(pow(r,2)-pow(r2,2))
dx1=x2-cx
dy1=y2-cy
dx = 0-dy1/r2*dd2
dy = dx1/r2*dd2
see "(" + (cx+dy) + ", " + (cy+dx) + ")" + nl
see "(" + (cx-dy) + ", " + (cy-dx) + ")" + nl + nl
</syntaxhighlight>
Output:
<pre>
1 : 0.1234 0.9876 0.8765 0.2345 2
(1.8631, 1.9742)
(-0.8632, -0.7521)
 
2 : 0 2 0 0 1
(0, 1)
(0, 1)
 
3 : 0.1234 0.9876 0.1234 0.9876 2
There are any number of circles via single point (0.1234,0.9876) of radius 2
 
4 : 0.1234 0.9876 0.8765 0.2345 0.5000
Points are too far apart (1.0650) - there are no circles of radius 0.5000
 
5 : 0.1234 0.9876 0.1234 0.9876 0
It will be a single point (0.1234,0.9876) of radius 0
</pre>
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">Pt = Struct.new(:x, :y)
Circle = Struct.new(:x, :y, :r)
 
Line 2,189 ⟶ 3,648:
end
puts
end</langsyntaxhighlight>
{{out}}
<pre>
Line 2,226 ⟶ 3,685:
#<struct Circle x=0.1234, y=0.9876, r=0.0>
</pre>
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="rnbasic">
html "<TABLE border=1>"
html "<tr bgcolor=wheat align=center><td>No.</td><td>x1</td><td>y1</td><td>x2</td><td>y2</td><td>r</td><td>cir x1</td><td>cir y1</td><td>cir x2</td><td>cir y2</td></tr>"
Line 2,274 ⟶ 3,732:
html "<td>";cx+dy;"</td><td>";cy+dx;"</td>" 'two points, with (+)
html "<td>";cx-dy;"</td><td>";cy-dx;"</td></TR>" 'and (-)
RETURN</langsyntaxhighlight>
{{Out}}<TABLE BORDER="1">
<TR ALIGN="CENTER" BGCOLOR="wheat"><TD>No.</TD><TD>x1</TD><TD>y1</TD><TD>x2
Line 2,288 ⟶ 3,746:
<TD ALIGN="LEFT" COLSPAN="4">It will be a single point (0.1234,0.9876) of radius 0</TD></TR>
</TABLE>
 
=={{header|Rust}}==
{{trans|C}}
<langsyntaxhighlight lang="rust">use std::fmt;
 
#[derive(Clone,Copy)]
Line 2,348 ⟶ 3,805:
describe_circle(p.0, p.1, r);
}
}</langsyntaxhighlight>
{{out}}
<pre>Points: ((0.1234, 0.9876), (0.8765, 0.2345)), Radius: 2.0000
Line 2,365 ⟶ 3,822:
Points: ((0.1234, 0.9876), (0.1234, 0.9876)), Radius: 0.0000
No circles can be drawn through (0.1234, 0.9876)</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">import org.scalatest.FunSuite
import math._
 
Line 2,421 ⟶ 3,877:
Circle(V2(mid.x + d * diff.y / diff.distance, mid.y - d * diff.x / diff.distance), abs(radius))).distinct
}
}</langsyntaxhighlight>
{{out}}
<pre> p1 p2 r result
Line 2,429 ⟶ 3,885:
(0.1234, 0.9876) (0.8765, 0.2345) 0.5: radius is less then the distance between points
(0.1234, 0.9876) (0.1234, 0.9876) 0.0: radius of zero yields no circlesEmpty test suite.</pre>
 
=={{header|Scheme}}==
 
<langsyntaxhighlight lang="scheme">
(import (scheme base)
(scheme inexact)
Line 2,495 ⟶ 3,950:
'((0.8765 0.2345) (0.0000 0.0000) (0.1234 0.9876) (0.8765 0.2345) (0.1234 0.9876))
'(2.0 1.0 2.0 0.5 0.0))
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,505 ⟶ 3,960:
p1: (0.1234 0.9876) p2: (0.1234 0.9876) r: 0.0 => ((0.1234 0.9876))
</pre>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
include "math.s7i";
Line 2,576 ⟶ 4,030:
point(cases[index][3], cases[index][4]), cases[index][5]);
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,593 ⟶ 4,047:
Radius of zero. No circles can be drawn through (0.1234, 0.9876)
</pre>
=={{header|Sidef}}==
{{trans|Raku}}
<syntaxhighlight lang="ruby">func circles(a, b, r) {
 
if (a == b) {
if (r == 0) {
return ['Degenerate point']
}
else {
return ['Infinitely many share a point']
}
}
 
var h = (b-a)/2
 
if (r**2 < h.norm) {
return ['Too far apart']
}
 
var l = sqrt(r**2 - h.norm)
 
[1i, -1i].map {|i|
a + h + (l*i*h / h.abs) -> round(-16)
}
}
 
var input = [
[0.1234 + 0.9876i, 0.8765 + 0.2345i, 2.0],
[0.0000 + 2.0000i, 0.0000 + 0.0000i, 1.0],
[0.1234 + 0.9876i, 0.1234 + 0.9876i, 2.0],
[0.1234 + 0.9876i, 0.8765 + 0.2345i, 0.5],
[0.1234 + 0.9876i, 0.1234 + 0.9876i, 0.0],
]
 
input.each {|a|
say (a.join(', '), ': ', circles(a...).join(' and '))
}</syntaxhighlight>
{{out}}
<pre>
0.1234+0.9876i, 0.8765+0.2345i, 2: 1.8631118016581891+1.9742118016581891i and -0.8632118016581891-0.7521118016581891i
2i, 0, 1: i and i
0.1234+0.9876i, 0.1234+0.9876i, 2: Infinitely many share a point
0.1234+0.9876i, 0.8765+0.2345i, 0.5: Too far apart
0.1234+0.9876i, 0.1234+0.9876i, 0: Degenerate point
</pre>
=={{header|Stata}}==
Each circle center is the image of B by the composition of a rotation and homothecy centered at A. It's how the centers are computed in this implementation. The coordinates are returned as the columns of a 2x2 matrix. When the solution is not unique or does not exist, this matrix contains only missing values.
 
<langsyntaxhighlight lang="stata">real matrix centers(real colvector a, real colvector b, real scalar r) {
real matrix rot
real scalar d, u, v
Line 2,615 ⟶ 4,113:
return(J(2, 2, .))
}
}</langsyntaxhighlight>
 
Examples:
 
<langsyntaxhighlight lang="stata">:a=0.1234\0.9876
:b=0.8765\0.2345
: centers(a,b,2)
Line 2,656 ⟶ 4,154:
1 | .1234 .1234 |
2 | .9876 .9876 |
+-----------------+</langsyntaxhighlight>
=={{header|Swift}}==
 
{{trans|F#}}
 
<syntaxhighlight lang="swift">import Foundation
 
struct Point: Equatable {
var x: Double
var y: Double
}
 
struct Circle {
var center: Point
var radius: Double
 
static func circleBetween(
_ p1: Point,
_ p2: Point,
withRadius radius: Double
) -> (Circle, Circle?)? {
func applyPoint(_ p1: Point, _ p2: Point, op: (Double, Double) -> Double) -> Point {
return Point(x: op(p1.x, p2.x), y: op(p1.y, p2.y))
}
 
func mul2(_ p: Point, mul: Double) -> Point {
return Point(x: p.x * mul, y: p.y * mul)
}
 
func div2(_ p: Point, div: Double) -> Point {
return Point(x: p.x / div, y: p.y / div)
}
 
func norm(_ p: Point) -> Point {
return div2(p, div: (p.x * p.x + p.y * p.y).squareRoot())
}
 
guard radius != 0, p1 != p2 else {
return nil
}
 
let diameter = 2 * radius
let pq = applyPoint(p1, p2, op: -)
let magPQ = (pq.x * pq.x + pq.y * pq.y).squareRoot()
 
guard diameter >= magPQ else {
return nil
}
 
let midpoint = div2(applyPoint(p1, p2, op: +), div: 2)
let halfPQ = magPQ / 2
let magMidC = abs(radius * radius - halfPQ * halfPQ).squareRoot()
let midC = mul2(norm(Point(x: -pq.y, y: pq.x)), mul: magMidC)
let center1 = applyPoint(midpoint, midC, op: +)
let center2 = applyPoint(midpoint, midC, op: -)
 
if center1 == center2 {
return (Circle(center: center1, radius: radius), nil)
} else {
return (Circle(center: center1, radius: radius), Circle(center: center2, radius: radius))
}
}
}
 
let testCases = [
(Point(x: 0.1234, y: 0.9876), Point(x: 0.8765, y: 0.2345), 2.0),
(Point(x: 0.0000, y: 2.0000), Point(x: 0.0000, y: 0.0000), 1.0),
(Point(x: 0.1234, y: 0.9876), Point(x: 0.1234, y: 0.9876), 2.0),
(Point(x: 0.1234, y: 0.9876), Point(x: 0.8765, y: 0.2345), 0.5),
(Point(x: 0.1234, y: 0.9876), Point(x: 0.1234, y: 0.9876), 0.0)
]
 
for testCase in testCases {
switch Circle.circleBetween(testCase.0, testCase.1, withRadius: testCase.2) {
case nil:
print("No ans")
case (let circle1, nil)?:
print("One ans: \(circle1)")
case (let circle1, let circle2?)?:
print("Two ans: \(circle1) \(circle2)")
}
}
 
</syntaxhighlight>
 
{{out}}
 
<pre>Two ans: Circle(center: Point(x: -0.8632118016581896, y: -0.7521118016581892), radius: 2.0) Circle(center: Point(x: 1.8631118016581893, y: 1.974211801658189), radius: 2.0)
One ans: Circle(center: Point(x: 0.0, y: 1.0), radius: 1.0)
No ans
No ans
No ans</pre>
=={{header|Tcl}}==
{{trans|Python}}
<langsyntaxhighlight lang="tcl">proc findCircles {p1 p2 r} {
lassign $p1 x1 y1
lassign $p2 x2 y2
Line 2,691 ⟶ 4,279:
set c2 [list [expr {$x3 + $f*$dy}] [expr {$y3 - $f*$dx}] $r]
return [list $c1 $c2]
}</langsyntaxhighlight>
 
{{out|Demo}}
<langsyntaxhighlight lang="tcl">foreach {p1 p2 r} {
{0.1234 0.9876} {0.8765 0.2345} 2.0
{0.0000 2.0000} {0.0000 0.0000} 1.0
Line 2,709 ⟶ 4,297:
puts "\tERROR: $msg"
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,725 ⟶ 4,313:
Circle:(0.1234, 0.9876, 0.0)
</pre>
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Public Sub circles()
tests = [{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}]
For i = 1 To UBound(tests)
x1 = tests(i, 1)
y1 = tests(i, 2)
x2 = tests(i, 3)
y2 = tests(i, 4)
R = tests(i, 5)
xd = x2 - x1
yd = y1 - y2
s2 = xd * xd + yd * yd
sep = Sqr(s2)
xh = (x1 + x2) / 2
yh = (y1 + y2) / 2
Dim txt As String
If sep = 0 Then
txt = "same points/" & IIf(R = 0, "radius is zero", "infinite solutions")
Else
If sep = 2 * R Then
txt = "opposite ends of diameter with centre " & xh & ", " & yh & "."
Else
If sep > 2 * R Then
txt = "too far apart " & sep & " > " & 2 * R
Else
md = Sqr(R * R - s2 / 4)
xs = md * xd / sep
ys = md * yd / sep
txt = "{" & Format(xh + ys, "0.0000") & ", " & Format(yh + xs, "0.0000") & _
"} and {" & Format(xh - ys, "0.0000") & ", " & Format(yh - xs, "0.0000") & "}"
End If
End If
End If
Debug.Print "points " & "{" & x1 & ", " & y1 & "}" & ", " & "{" & x2 & ", " & y2 & "}" & " with radius " & R & " ==> " & txt
Next i
End Sub</syntaxhighlight>{{out}}
<pre>points {0,1234, 0,9876}, {0,8765, 0,2345} with radius 2 ==> {1,8631, 1,9742} and {-0,8632, -0,7521}
points {0, 2}, {0, 0} with radius 1 ==> opposite ends of diameter with centre 0, 1.
points {0,1234, 0,9876}, {0,1234, 0,9876} with radius 2 ==> same points/infinite solutions
points {0,1234, 0,9876}, {0,8765, 0,2345} with radius 0,5 ==> too far apart 1,06504423382318 > 1
points {0,1234, 0,9876}, {0,1234, 0,9876} with radius 0 ==> same points/radius is zero</pre>
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Public Class CirclesOfGivenRadiusThroughTwoPoints
Public Shared Sub Main()
For Each valu In New Double()() {
New Double() {0.1234, 0.9876, 0.8765, 0.2345, 2},
New Double() {0.0, 2.0, 0.0, 0.0, 1},
New Double() {0.1234, 0.9876, 0.1234, 0.9876, 2},
New Double() {0.1234, 0.9876, 0.8765, 0.2345, 0.5},
New Double() {0.1234, 0.9876, 0.1234, 0.9876, 0},
New Double() {0.1234, 0.9876, 0.2345, 0.8765, 0}}
Dim p = New Point(valu(0), valu(1)), q = New Point(valu(2), valu(3))
Console.WriteLine($"Points {p} and {q} with radius {valu(4)}:")
Try
Console.WriteLine(vbTab & String.Join(" and ", FindCircles(p, q, valu(4))))
Catch ex As Exception
Console.WriteLine(vbTab & ex.Message)
End Try
Next
If System.Diagnostics.Debugger.IsAttached Then Console.ReadKey()
End Sub
 
Private Shared Function FindCircles(ByVal p As Point, ByVal q As Point, ByVal rad As Double) As Point()
If rad < 0 Then Throw New ArgumentException("Negative radius.")
If rad = 0 Then Throw New InvalidOperationException(If(p = q,
String.Format("{0} (degenerate circle)", {p}), "No circles."))
If p = q Then Throw New InvalidOperationException("Infinite number of circles.")
Dim dist As Double = Point.Distance(p, q), sqDist As Double = dist * dist,
sqDiam As Double = 4 * rad * rad
If sqDist > sqDiam Then Throw New InvalidOperationException(
String.Format("Points are too far apart (by {0}).", sqDist - sqDiam))
Dim midPoint As Point = New Point((p.X + q.X) / 2, (p.Y + q.Y) / 2)
If sqDist = sqDiam Then Return {midPoint}
Dim d As Double = Math.Sqrt(rad * rad - sqDist / 4),
a As Double = d * (q.X - p.X) / dist, b As Double = d * (q.Y - p.Y) / dist
Return {New Point(midPoint.X - b, midPoint.Y + a), New Point(midPoint.X + b, midPoint.Y - a)}
End Function
 
Public Structure Point
Public ReadOnly Property X As Double
Public ReadOnly Property Y As Double
 
Public Sub New(ByVal ix As Double, ByVal iy As Double)
Me.New() : X = ix : Y = iy
End Sub
 
Public Shared Operator =(ByVal p As Point, ByVal q As Point) As Boolean
Return p.X = q.X AndAlso p.Y = q.Y
End Operator
 
Public Shared Operator <>(ByVal p As Point, ByVal q As Point) As Boolean
Return p.X <> q.X OrElse p.Y <> q.Y
End Operator
 
Public Shared Function SquaredDistance(ByVal p As Point, ByVal q As Point) As Double
Dim dx As Double = q.X - p.X, dy As Double = q.Y - p.Y
Return dx * dx + dy * dy
End Function
 
Public Shared Function Distance(ByVal p As Point, ByVal q As Point) As Double
Return Math.Sqrt(SquaredDistance(p, q))
End Function
 
Public Overrides Function ToString() As String
Return $"({X}, {Y})"
End Function
End Structure
End Class</syntaxhighlight>
{{out}}
<pre>Points (0.1234, 0.9876) and (0.8765, 0.2345) with radius 2:
(1.86311180165819, 1.97421180165819) and (-0.86321180165819, -0.752111801658189)
Points (0, 2) and (0, 0) with radius 1:
(0, 1)
Points (0.1234, 0.9876) and (0.1234, 0.9876) with radius 2:
Infinite number of circles.
Points (0.1234, 0.9876) and (0.8765, 0.2345) with radius 0.5:
Points are too far apart (by 0.13431922).
Points (0.1234, 0.9876) and (0.1234, 0.9876) with radius 0:
(0.1234, 0.9876) (degenerate circle)
Points (0.1234, 0.9876) and (0.2345, 0.8765) with radius 0:
No circles.</pre>
=={{header|Visual FoxPro}}==
Translation of BASIC.
<langsyntaxhighlight lang="vfp">
LOCAL p1 As point, p2 As point, rr As Double
CLOSE DATABASES ALL
Line 2,813 ⟶ 4,522:
 
ENDDEFINE
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,842 ⟶ 4,551:
Points (0.1234,0.9876), (0.1234,0.9876) Radius 0.0000.
Points are coincident.
</pre>
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">import math
 
const (
two = "two circles."
r0 = "R==0.0 does not describe circles."
co = "coincident points describe an infinite number of circles."
cor0 = "coincident points with r==0.0 describe a degenerate circle."
diam = "Points form a diameter and describe only a single circle."
far = "Points too far apart to form circles."
)
struct Point {
x f64
y f64
}
fn circles(p1 Point, p2 Point, r f64) (Point, Point, string) {
mut case := ''
c1, c2 := p1, p2
if p1 == p2 {
if r == 0 {
return p1, p1, cor0
}
case = co
return c1, c2, case
}
if r == 0 {
return p1, p2, r0
}
dx := p2.x - p1.x
dy := p2.y - p1.y
q := math.hypot(dx, dy)
if q > 2*r {
case = far
return c1, c2, case
}
m := Point{(p1.x + p2.x) / 2, (p1.y + p2.y) / 2}
if q == 2*r {
return m, m, diam
}
d := math.sqrt(r*r - q*q/4)
ox := d * dx / q
oy := d * dy / q
return Point{m.x - oy, m.y + ox}, Point{m.x + oy, m.y - ox}, two
}
 
struct Cir {
p1 Point
p2 Point
r f64
}
const td = [
Cir{Point{0.1234, 0.9876}, Point{0.8765, 0.2345}, 2.0},
Cir{Point{0.0000, 2.0000}, Point{0.0000, 0.0000}, 1.0},
Cir{Point{0.1234, 0.9876}, Point{0.1234, 0.9876}, 2.0},
Cir{Point{0.1234, 0.9876}, Point{0.8765, 0.2345}, 0.5},
Cir{Point{0.1234, 0.9876}, Point{0.1234, 0.9876}, 0.0},
]
fn main() {
for tc in td {
println("p1: $tc.p1")
println("p2: $tc.p2")
println("r: $tc.r")
c1, c2, case := circles(tc.p1, tc.p2, tc.r)
println(" $case")
match case {
cor0, diam{
println(" Center: $c1")
}
two {
println(" Center 1: $c1")
println(" Center 2: $c2")
}
else{}
}
println('')
}
}</syntaxhighlight>
 
{{out}}
<pre>
p1: Point{
x: 0.1234
y: 0.9876
}
p2: Point{
x: 0.8765
y: 0.2345
}
r: 2
two circles.
Center 1: Point{
x: 1.863111801658189
y: 1.9742118016581887
}
Center 2: Point{
x: -0.8632118016581891
y: -0.7521118016581888
}
 
p1: Point{
=={{header|XPL0}}==
x: 0
An easy way to solve this:
y: 2
translate the coordinates so that one point is at the origin.
}
Then rotate the coordinate frame so that the second point is on the X-axis.
p2: Point{
The circles' X coordinate is then half the distance to the second point.
x: 0
The circles' Y coordinates are easily seen as +/-sqrt(radius^2 - circleX^2).
y: 0
Now undo the rotation and translation.
}
The method used here is a streamlining of these steps.
r: 1
Points form a diameter and describe only a single circle.
Center: Point{
x: 0
y: 1
}
 
p1: Point{
<lang XPL0>include c:\cxpl\codes;
x: 0.1234
y: 0.9876
}
p2: Point{
x: 0.1234
y: 0.9876
}
r: 2
coincident points describe an infinite number of circles.
 
p1: Point{
proc Circles; real Data; \Show centers of circles, given points P & Q and radius
x: 0.1234
real Px, Py, Qx, Qy, R, X, Y, X1, Y1, Bx, By, PB, CB;
y: 0.9876
[Px:= Data(0); Py:= Data(1); Qx:= Data(2); Qy:= Data(3); R:= Data(4);
}
if R = 0.0 then [Text(0, "Radius = zero gives no circles^M^J"); return];
p2: Point{
X:= (Qx-Px)/2.0; Y:= (Qy-Py)/2.0;
Bx:= Px+X; By x:= Py+Y;0.8765
y: 0.2345
PB:= sqrt(X*X + Y*Y);
}
if PB = 0.0 then [Text(0, "Coincident points give infinite circles^M^J"); return];
r: 0.5
if PB > R then [Text(0, "Points are too far apart for radius^M^J"); return];
Points too far apart to form circles.
CB:= sqrt(R*R - PB*PB);
X1:= Y*CB/PB; Y1:= X*CB/PB;
RlOut(0, Bx-X1); ChOut(0, ^,); RlOut(0, By+Y1); ChOut(0, 9\tab\);
RlOut(0, Bx+X1); ChOut(0, ^,); RlOut(0, By-Y1); CrLf(0);
];
 
p1: Point{
real Tbl; int I;
x: 0.1234
[Tbl:=[[0.1234, 0.9876, 0.8765, 0.2345, 2.0],
y: 0.9876
[0.0000, 2.0000, 0.0000, 0.0000, 1.0],
}
[0.1234, 0.9876, 0.1234, 0.9876, 2.0],
p2: Point{
[0.1234, 0.9876, 0.8765, 0.2345, 0.5],
x: [0.1234, 0.9876, 0.1234, 0.9876, 0.0]];
y: 0.9876
for I:= 0 to 4 do Circles(Tbl(I));
}
]</lang>
r: 0
coincident points with r==0.0 describe a degenerate circle.
Center: Point{
x: 0.1234
y: 0.9876
}
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-math}}
<syntaxhighlight lang="wren">import "./math" for Math
 
var Two = "Two circles."
var R0 = "R == 0 does not describe circles."
var Co = "Coincident points describe an infinite number of circles."
var CoR0 = "Coincident points with r == 0 describe a degenerate circle."
var Diam = "Points form a diameter and describe only a single circle."
var Far = "Points too far apart to form circles."
 
class Point {
construct new(x, y) {
_x = x
_y = y
}
 
x { _x }
y { _y }
==(p) { _x == p.x && _y == p.y }
 
toString { "(%(_x), %(_y))" }
}
 
var circles = Fn.new { |p1, p2, r|
var c1 = Point.new(0, 0)
var c2 = Point.new(0, 0)
if (p1 == p2) {
if (r == 0) return [p1, p1, CoR0]
return [c1, c2, Co]
}
if (r == 0) return [p1, p2, R0]
var dx = p2.x - p1.x
var dy = p2.y - p1.y
var q = Math.hypot(dx, dy)
if (q > 2*r) return [c1, c2, Far]
var m = Point.new((p1.x + p2.x)/2, (p1.y + p2.y)/2)
if (q == 2*r) return [m, m, Diam]
var d = (r*r - q*q/4).sqrt
var ox = d * dx / q
var oy = d * dy / q
return [Point.new(m.x - oy, m.y + ox), Point.new(m.x + oy, m.y - ox), Two]
}
 
var td = [
[Point.new(0.1234, 0.9876), Point.new(0.8765, 0.2345), 2.0],
[Point.new(0.0000, 2.0000), Point.new(0.0000, 0.0000), 1.0],
[Point.new(0.1234, 0.9876), Point.new(0.1234, 0.9876), 2.0],
[Point.new(0.1234, 0.9876), Point.new(0.8765, 0.2345), 0.5],
[Point.new(0.1234, 0.9876), Point.new(0.1234, 0.9876), 0.0]
]
for (tc in td) {
System.print("p1: %(tc[0])")
System.print("p2: %(tc[1])")
System.print("r : %(tc[2])")
var res = circles.call(tc[0], tc[1], tc[2])
System.print(" %(res[2])")
if (res[2] == CoR0 || res[2] == Diam) {
System.print(" Center: %(res[0])")
} else if (res[2] == Two) {
System.print(" Center 1: %(res[0])")
System.print(" Center 2: %(res[1])")
}
System.print()
}</syntaxhighlight>
 
{{out}}
<pre>
p1: (0.1234, 0.9876)
1.86311, 1.97421 -0.86321, -0.75211
p2: (0.8765, 0.2345)
0.00000, 1.00000 0.00000, 1.00000
r : 2
Coincident points give infinite circles
Two circles.
Points are too far apart for radius
Center 1: (1.8631118016582, 1.9742118016582)
Radius = zero gives no circles
Center 2: (-0.86321180165819, -0.75211180165819)
 
p1: (0, 2)
p2: (0, 0)
r : 1
Points form a diameter and describe only a single circle.
Center: (0, 1)
 
p1: (0.1234, 0.9876)
p2: (0.1234, 0.9876)
r : 2
Coincident points describe an infinite number of circles.
 
p1: (0.1234, 0.9876)
p2: (0.8765, 0.2345)
r : 0.5
Points too far apart to form circles.
 
p1: (0.1234, 0.9876)
p2: (0.1234, 0.9876)
r : 0
Coincident points with r == 0 describe a degenerate circle.
Center: (0.1234, 0.9876)
</pre>
 
Line 2,897 ⟶ 4,816:
The method used here is a streamlining of these steps.
 
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes;
 
proc Circles; real Data; \Show centers of circles, given points P & Q and radius
Line 2,921 ⟶ 4,840:
[0.1234, 0.9876, 0.1234, 0.9876, 0.0]];
for I:= 0 to 4 do Circles(Tbl(I));
]</langsyntaxhighlight>
 
{{out}}
Line 2,931 ⟶ 4,850:
Radius = zero gives no circles
</pre>
=={{header|Yabasic}}==
{{trans|Liberty BASIC}}
<syntaxhighlight lang="yabasic">
sub twoCircles (x1, y1, x2, y2, radio)
if x1 = x2 and y1 = y2 then //Si los puntos coinciden
if radio = 0 then //a no ser que radio=0
print "Los puntos son los mismos\n"
return true
else
print "Hay cualquier numero de circulos a traves de un solo punto (", x1, ",", y1, ") de radio ", radio : print
return true
end if
end if
r2 = sqr((x1-x2)^2+(y1-y2)^2) / 2 //distancia media entre puntos
if radio < r2 then
print "Los puntos estan demasiado separados (", 2*r2, ") - no hay circulos de radio ", radio : print
return true
end if
 
//si no, calcular dos centros
cx = (x1+x2) / 2 //punto medio
cy = (y1+y2) / 2
//debe moverse desde el punto medio a lo largo de la perpendicular en dd2
dd2 = sqr(radio^2 - r2^2) //distancia perpendicular
dx1 = x2-cx //vector al punto medio
dy1 = y2-cy
dx = 0-dy1 / r2*dd2 //perpendicular:
dy = dx1 / r2*dd2 //rotar y escalar
print " -> Circulo 1 (", cx+dy, ", ", cy+dx, ")" //dos puntos, con (+)
print " -> Circulo 2 (", cx-dy, ", ", cy-dx, ")\n" //y (-)
end sub
 
for i = 1 to 5
read x1, y1, x2, y2, radio
print "Puntos ", "(", x1, ",", y1, "), (", x2, ",", y2, ")", ", Radio ", radio
twoCircles (x1, y1, x2, y2, radio)
next
end
 
//p1 p2 radio
data 0.1234, 0.9876, 0.8765, 0.2345, 2.0
data 0.0000, 2.0000, 0.0000, 0.0000, 1.0
data 0.1234, 0.9876, 0.1234, 0.9876, 2.0
data 0.1234, 0.9876, 0.8765, 0.2345, 0.5
data 0.1234, 0.9876, 0.1234, 0.9876, 0.0
 
</syntaxhighlight>
=={{header|zkl}}==
{{trans|C}}
<langsyntaxhighlight lang="zkl">fcn findCircles(a,b, c,d, r){ //-->T(T(x,y,r) [,T(x,y,r)]))
delta:=(a-c).hypot(b-d);
switch(delta){ // could just catch MathError
Line 2,968 ⟶ 4,933:
else print(cs);
println();
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,982 ⟶ 4,947:
Circles: singularity
</pre>
 
=={{header|ZX Spectrum Basic}}==
{{trans|Liberty BASIC}}
<langsyntaxhighlight lang="zxbasic">10 FOR i=1 TO 5
20 READ x1,y1,x2,y2,r
30 PRINT i;") ";x1;" ";y1;" ";x2;" ";y2;" ";r
Line 3,011 ⟶ 4,975:
1190 PRINT "(";cx+dy;",";cy+dx;")"
1200 PRINT "(";cx-dy;",";cy-dx;")"
1210 RETURN</langsyntaxhighlight>
 
[[Category:Geometry]]
1,480

edits