Problem of Apollonius: Difference between revisions
m
→{{header|EasyLang}}
(12 intermediate revisions by 9 users not shown) | |||
Line 16:
{{trans|Python}}
<
Float x, y, r
Line 69:
V (c1, c2, c3) = (Circle(0, 0, 1), Circle(4, 0, 1), Circle(2, 4, 2))
print(solveApollonius(c1, c2, c3, 1, 1, 1))
print(solveApollonius(c1, c2, c3, -1, -1, -1))</
{{out}}
Line 79:
=={{header|Ada}}==
apollonius.ads:
<
type Point is record
X, Y : Long_Float := 0.0;
Line 95:
T1, T2, T3 : Tangentiality := External)
return Circle;
end Apollonius;</
apollonius.adb:
<
package body Apollonius is
Line 182:
end;
end Solve_CCC;
end Apollonius;</
example test_apollonius.adb:
<
with Apollonius;
Line 209:
Long_Float_IO.Put (R2.Radius, Aft => 3, Exp => 0);
Ada.Text_IO.New_Line;
end Test_Apollonius;</
output:
Line 216:
R2:
2.000 0.833 1.167</pre>
=={{header|ALGOL 68}}==
{{Trans|Java|Algol 68 doesn't actually do javadoc comments but they seemed useful...}}
<syntaxhighlight lang="algol68">
BEGIN # solve the problem of Apollonius - find circles tangential to 3 others #
# translation of the Java sample #
OP FMT = ( REAL v )STRING:
BEGIN
STRING result := fixed( v, -12, 2 );
INT start := LWB result;
WHILE IF start >= UPB result THEN FALSE ELSE result[ start ] = " " FI DO start +:= 1 OD;
result[ start : ]
END # FMT # ;
MODE CIRCLE = STRUCT( REAL x, y, radius );
OP TOSTRING = ( CIRCLE c )STRING:
"Circle[x=" + FMT x OF c + ",y=" + FMT y OF c + ",r=" + FMT radius OF c + "]";
### Solves the Problem of Apollonius (finding a circle tangential to three other
* circles in the plane). The method uses approximately 68 heavy operations
* (multiplication, division, square-roots).
* @param c1 One of the circles in the problem
* @param c2 One of the circles in the problem
* @param c3 One of the circles in the problem
* @param s1 An indication if the solution should be externally or internally
* tangent (+1/-1) to c1
* @param s2 An indication if the solution should be externally or internally
* tangent (+1/-1) to c2
* @param s3 An indication if the solution should be externally or internally
* tangent (+1/-1) to c3
* @return The circle that is tangent to c1, c2 and c3.
#
PROC solve apollonius = ( CIRCLE c1, c2, c3, INT s1, s2, s3 )CIRCLE:
BEGIN
REAL x1 = x OF c1;
REAL y1 = y OF c1;
REAL r1 = radius OF c1;
REAL x2 = x OF c2;
REAL y2 = y OF c2;
REAL r2 = radius OF c2;
REAL x3 = x OF c3;
REAL y3 = y OF c3;
REAL r3 = radius OF c3;
REAL v11 = 2*x2 - 2*x1;
REAL v12 = 2*y2 - 2*y1;
REAL v13 = x1*x1 - x2*x2 + y1*y1 - y2*y2 - r1*r1 + r2*r2;
REAL v14 = 2*s2*r2 - 2*s1*r1;
REAL v21 = 2*x3 - 2*x2;
REAL v22 = 2*y3 - 2*y2;
REAL v23 = x2*x2 - x3*x3 + y2*y2 - y3*y3 - r2*r2 + r3*r3;
REAL v24 = 2*s3*r3 - 2*s2*r2;
REAL w12 = v12/v11;
REAL w13 = v13/v11;
REAL w14 = v14/v11;
REAL w22 = v22/v21-w12;
REAL w23 = v23/v21-w13;
REAL w24 = v24/v21-w14;
REAL p = -w23/w22;
REAL q = w24/w22;
REAL m = -w12*p-w13;
REAL n = w14 - w12*q;
REAL a = n*n + q*q - 1;
REAL b = 2*m*n - 2*n*x1 + 2*p*q - 2*q*y1 + 2*s1*r1;
REAL c = x1*x1 + m*m - 2*m*x1 + p*p + y1*y1 - 2*p*y1 - r1*r1;
# Find a root of a quadratic equation. This requires the circle centers not #
# to be e.g. colinear #
REAL d = b*b-4*a*c;
REAL rs = (-b-sqrt(d))/(2*a);
REAL xs = m + n * rs;
REAL ys = p + q * rs;
( xs, ys, rs )
END # solve apollonius # ;
CIRCLE c1 = ( 0, 0, 1 );
CIRCLE c2 = ( 4, 0, 1 );
CIRCLE c3 = ( 2, 4, 2 );
# should output "Circle[x=2.00,y=2.10,r=3.90]" (green circle in image) #
print( ( TOSTRING solve apollonius( c1, c2, c3, 1, 1, 1 ), newline ) );
# should output "Circle[x=2.00,y=0.83,r=1.17]" (red circle in image) #
print( ( TOSTRING solve apollonius( c1, c2, c3, -1, -1,-1 ), newline ) )
END
</syntaxhighlight>
{{out}}
<pre>
Circle[x=2.00,y=2.10,r=3.90]
Circle[x=2.00,y=0.83,r=1.17]
</pre>
=={{header|Arturo}}==
Line 221 ⟶ 319:
{{trans|Nim}}
<
solveApollonius: function [c1 c2 c3 s1 s2 s3][
Line 265 ⟶ 363:
print solveApollonius c1 c2 c3 1.0 1.0 1.0
print solveApollonius c1 c2 c3 neg 1.0 neg 1.0 neg 1.0</
{{out}}
Line 274 ⟶ 372:
=={{header|AutoHotkey}}==
{{libheader|GDIP}}
<
#SingleInstance, Force
SetBatchLines, -1
Line 378 ⟶ 476:
Gdip_DrawCircle(G, pPen, x, y, r) {
Return Gdip_DrawEllipse(G, pPen, x-r, y-r, r*2, r*2)
}</
=={{header|BASIC256}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">
circle1$ = " 0.000, 0.000, 1.000"
circle2$ = " 4.000, 0.000, 1.000"
Line 436 ⟶ 534:
print "R2: " : call ApolloniusSolver(circle1$, circle2$, circle3$, -1, -1, -1)
end
</syntaxhighlight>
Line 442 ⟶ 540:
{{works with|BBC BASIC for Windows}}
Note use made of array arithmetic.
<
DIM Circles{(2)} = Circle{}
Circles{(0)}.x = 0 : Circles{(0)}.y = 0 : Circles{(0)}.r = 1
Line 478 ⟶ 576:
c.x = c.r * w(2) - w(1)
c.y = c.r * u(2) - u(1)
ENDPROC</
'''Output:'''
<pre>
Line 487 ⟶ 585:
=={{header|C}}==
C99. 2D vectors are actually complex numbers. The method here is unothordox if not insane. I can't prove that it should work, though it does seem to give correct answers for test cases I tried.
<
#include <tgmath.h>
Line 596 ⟶ 694:
puts("set 2"); apollonius(b);
puts("set 3"); apollonius(c);
}</
=={{header|C sharp|C#}}==
This code finds all 8 possible circles touching the three given circles.
<
using System;
Line 757 ⟶ 855:
}
}
</syntaxhighlight>
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <cmath>
#include <iostream>
#include <stdexcept>
struct Circle {
double x;
double y;
double radius;
void display() {
std::cout << "centre(" << x << ", " << y << ")" << ", radius = " << radius << std::endl;
}
};
double square(const double& value) {
return value * value;
}
/**
* The parameters s1, s2, s3 indicate whether the result circle is
* internally tangent to the corresponding argument circle (-1), or
* externally tangent to the corresponding argument circle (+1).
*/
Circle solve_apollonius(const Circle& circle1, const Circle& circle2, const Circle& circle3,
const double& s1, const double& s2, const double& s3) {
if ( abs(s1) != 1 || abs(s2) != 1 || abs(s3) != 1 ) {
throw std::invalid_argument("Parameters s1, s2, s3 must be +1 or -1");
}
const double v11 = 2 * circle2.x - 2 * circle1.x;
const double v12 = 2 * circle2.y - 2 * circle1.y;
const double v13 = square(circle1.x) - square(circle2.x) + square(circle1.y) - square(circle2.y)
- square(circle1.radius) + square(circle2.radius);
const double v14 = 2 * s2 * circle2.radius - 2 * s1 * circle1.radius;
const double v21 = 2 * circle3.x - 2 * circle2.x;
const double v22 = 2 * circle3.y - 2 * circle2.y;
const double v23 = square(circle2.x) - square(circle3.x) + square(circle2.y) - square(circle3.y)
- square(circle2.radius) + square(circle3.radius);
const double v24 = 2 * s3 * circle3.radius - 2 * s2 * circle2.radius;
const double w12 = v12 / v11;
const double w13 = v13 / v11;
const double w14 = v14 / v11;
const double w22 = v22 / v21 - w12;
const double w23 = v23 / v21 - w13;
const double w24 = v24 / v21 - w14;
const double p = -w23 / w22;
const double q = w24 / w22;
const double m = -w12 * p - w13;
const double n = w14 - w12 * q;
const double a = square(n) + square(q) - 1;
const double b = 2 * m * n - 2 * n * circle1.x + 2 * p * q - 2 * q * circle1.y + 2 * s1 * circle1.radius;
const double c = square(circle1.x) + square(m) - 2 * m * circle1.x + square(p)
+ square(circle1.y) - 2 * p * circle1.y - square(circle1.radius);
const double discriminant = b * b - 4 * a * c;
const double root = ( -b - sqrt(discriminant) ) / ( 2 * a );
const double centre_x = m + n * root;
const double centre_y = p + q * root;
return Circle(centre_x, centre_y, root);
}
int main() {
Circle circle1(0.0, 0.0, 1.0);
Circle circle2(4.0, 0.0, 1.0);
Circle circle3(2.0, 4.0, 2.0);
std::cout << "The three initial circles are:" << std::endl;
std::cout << " Circle 1: "; circle1.display();
std::cout << " Circle 2: "; circle2.display();
std::cout << " Circle 3: "; circle3.display();
std::cout << std::endl;
std::cout << "The internal circle is: "; solve_apollonius(circle1, circle2, circle3, -1.0, -1.0, -1.0).display();
std::cout << "The external circle is: "; solve_apollonius(circle1, circle2, circle3, 1.0, 1.0, 1.0).display();
}
</syntaxhighlight>
{{ out }}
<pre>
The three initial circles are:
Circle 1: centre(0, 0), radius = 1
Circle 2: centre(4, 0), radius = 1
Circle 3: centre(2, 4), radius = 2
The internal circle is: centre(2, 0.833333), radius = 1.16667
The external circle is: centre(2, 2.1), radius = 3.9
</pre>
=={{header|CoffeeScript}}==
{{trans|Java}}
<
class Circle
constructor: (@x, @y, @r) ->
Line 814 ⟶ 1,007:
console.log apollonius(c1, c2, c3, -1, -1, -1)
</syntaxhighlight>
output
<syntaxhighlight lang="text">
> coffee foo.coffee
{ x: 0, y: 0, r: 1 }
Line 823 ⟶ 1,016:
{ x: 2, y: 2.1, r: 3.9 }
{ x: 2, y: 0.8333333333333333, r: 1.1666666666666667 }
</syntaxhighlight>
=={{header|D}}==
{{trans|Java}}
<
immutable struct Circle { double x, y, r; }
Line 906 ⟶ 1,099:
alias Ti = Tangent.internally;
solveApollonius(c1, c2, c3, Ti, Ti, Ti).writeln;
}</
{{out}}
<pre>immutable(Circle)(2, 2.1, 3.9)
Line 914 ⟶ 1,107:
=={{header|Dyalect}}==
{{trans|Swift}}
<
func Circle.
"Circle[x=\(this
func solveApollonius(Circle c1, Circle c2, Circle c3, Float s1, Float s2, Float s3) {
let x1 = c1
let y1 = c1
let r1 = c1
let x2 = c2
let y2 = c2
let r2 = c2
let x3 = c3
let y3 = c3
let r3 = c3
let v11 = 2.0 * x2 - 2.0 * x1
Line 969 ⟶ 1,162:
print(solveApollonius(c1, c2, c3, 1.0, 1.0, 1.0))
print(solveApollonius(c1, c2, c3, -1.0, -1.0, -1.0))</
{{out}}
Line 975 ⟶ 1,168:
<pre>Circle[x=2,y=2.1,r=3.9]
Circle[x=2,y=0.8333333333333333,r=1.1666666666666667]</pre>
=={{header|EasyLang}}==
[https://easylang.online/show/#cod=bVRNb5tAFLzvrxgllwQE3g/aWKq45WrLOVsc8JqmVl3jLtSGf1+99xabRJEttDNv3uzwgD2H1qNrj5cG3mwreEsXt63QGXQWnUOOsK2QKwDH5sTAERgMSmoyFX5gjMASCBG4inWWkI26CEQXQdQ5Qi7qIhBdBKJ7BF0vhjaxSMg/k4WRgo2FcSqMsUA2g2ElMurj5pTCkwgZtcS+QFwwSCllgmDFoojenZBxg07ELLG3XG7KJb32lmsqjLHAuW63MjhpTmdpRjf1xTSUi7jgxOKWS8gp1z36lcdCw1nQ7IRyTLk5VTBVzCjOTekXfHMZWUmB262bFZwU2MQWs0JBhQ1KZFduuFr2eEPJ8huxYomh3Ju745pkppC9keCNyBol1kiwRoo3IpGBE+/iLFZclEms5amnEGdRs5U8+vTzc/SzdyVlq1XsWE3khq3mr89kziDczeSVfUWJHRLskKFAghoJPBVChxJPGfHd39Dj9RkLPJFZ/cx1+iZKrJDyfYROSEvkJt79RDoiQ6dyxd9ziS00NAwqxd82EcVEuEhYFLCo1JcHgeFfMNtKncPh1MvyS2lm4j/Yu5qWj1BnOmn8IXgMGBGQy5HSN0OPhwda/mwDP1SNvoX7romjQ+dwajAgRXc48cwCRqTwbSeIZLnKZYN9qK/w7RGezizZwrfHNtCVASXwNNAERiOF0/A0yjl0AlWudrX//R7af6c9lsul8semDooSXQ/7/hd0/k2JvdZa0ebv4bBXf9pLQ06apbQyWgur4SJrNK85sdaaZzlD9gNyNPJj05x5S+FfdHwUH/kXrWXo6j8= Run it]
{{trans|Java}}
<syntaxhighlight>
proc solve c1[] c2[] c3[] s1 s2 s3 . r[] .
len r[] 3
x1 = c1[1] ; y1 = c1[2] ; r1 = c1[3]
x2 = c2[1] ; y2 = c2[2] ; r2 = c2[3]
x3 = c3[1] ; y3 = c3[2] ; r3 = c3[3]
#
v11 = 2 * x2 - 2 * x1
v12 = 2 * y2 - 2 * y1
v13 = x1 * x1 - x2 * x2 + y1 * y1 - y2 * y2 - r1 * r1 + r2 * r2
v14 = 2 * s2 * r2 - 2 * s1 * r1
v21 = 2 * x3 - 2 * x2
v22 = 2 * y3 - 2 * y2
v23 = x2 * x2 - x3 * x3 + y2 * y2 - y3 * y3 - r2 * r2 + r3 * r3
v24 = 2 * s3 * r3 - 2 * s2 * r2
w12 = v12 / v11
w13 = v13 / v11
w14 = v14 / v11
w22 = v22 / v21 - w12
w23 = v23 / v21 - w13
w24 = v24 / v21 - w14
P = -w23 / w22
Q = w24 / w22
M = -w12 * P - w13
N = w14 - w12 * Q
a = N * N + Q * Q - 1
b = 2 * M * N - 2 * N * x1 + 2 * P * Q - 2 * Q * y1 + 2 * s1 * r1
c = x1 * x1 + M * M - 2 * M * x1 + P * P + y1 * y1 - 2 * P * y1 - r1 * r1
#
D = b * b - 4 * a * c
rs = (-b - sqrt D) / (2 * a)
r[1] = M + N * rs
r[2] = P + Q * rs
r[3] = rs
.
c1[] = [ 0 0 1 ]
c2[] = [ 4 0 1 ]
c3[] = [ 2 4 2 ]
solve c1[] c2[] c3[] 1 1 1 r1[]
print r1[]
solve c1[] c2[] c3[] -1 -1 -1 r2[]
print r2[]
#
proc circ x y r . .
text ""
for a = 0 to 360
line x + sin a * r y + cos a * r
.
.
proc draw col c[] . .
color col
circ c[1] * 10 + 30 c[2] * 10 + 30 c[3] * 10
.
background 888
clear
linewidth 0.5
color 000
drawgrid
move 30 0
line 30 100
move 0 30
line 100 30
draw 000 c1[]
draw 000 c2[]
draw 000 c3[]
sleep 0.5
draw 070 r1[]
sleep 0.5
draw 700 r2[]
</syntaxhighlight>
{{out}}
<pre>
[ 2 2.10 3.90 ]
[ 2 0.83 1.17 ]
</pre>
=={{header|Elixir}}==
{{trans|Ruby}}
<
def apollonius(c1, c2, c3, s1, s2, s3) do
{x1, y1, r1} = c1
Line 1,010 ⟶ 1,283:
IO.inspect Circle.apollonius(c1, c2, c3, 1, 1, 1)
IO.inspect Circle.apollonius(c1, c2, c3, -1, -1, -1)</
{{out}}
Line 1,020 ⟶ 1,293:
=={{header|F_Sharp|F#}}==
{{trans|OCaml}}
<
type circle = { center: point; radius: float; }
Line 1,086 ⟶ 1,359:
let r2 = solve_apollonius c1 c2 c3 (-1.) (-1.) (-1.)
print_circle r2
0</
{{out}}
<pre>Circle(x=2.00, y=2.10, r=3.90)
Line 1,093 ⟶ 1,366:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
implicit none
Line 1,164 ⟶ 1,437:
end function
end program</
Output
<pre>External tangent: 2.00000000 2.10000000 3.90000000
Line 1,172 ⟶ 1,445:
=={{header|FreeBASIC}}==
{{trans|Liberty BASIC}}
<
Dim As String circle1 = " 0.000, 0.000, 1.000"
Dim As String circle2 = " 4.000, 0.000, 1.000"
Line 1,231 ⟶ 1,504:
Print "R2: " : ApolloniusSolver(circle1, circle2, circle3, -1, -1, -1)
Sleep
</syntaxhighlight>
{{out}}
<pre>
Line 1,247 ⟶ 1,520:
=={{header|FutureBasic}}==
<
include "NSLog.incl"
Line 1,335 ⟶ 1,608:
HandleEvents
</syntaxhighlight>
Output
<pre>External Tangent: Circle( x = 2.000, y = 2.100, radius = 3.900 )
Line 1,343 ⟶ 1,616:
{{trans|Java}}
Simplified to produce only the fully interior and fully exterior solutions.
<
import (
Line 1,406 ⟶ 1,679:
rs := (-b - math.Sqrt(d)) / (2 * a)
return circle{m + n*rs, p + q*rs, rs}
}</
Output:
<pre>
Line 1,415 ⟶ 1,688:
=={{header|Haskell}}==
{{trans|D}}
<
data Tangent = Externally | Internally deriving Eq
Line 1,489 ⟶ 1,762:
let ti = Internally
print $ solveApollonius c1 c2 c3 ti ti ti</
{{out}}
<pre>Circle {x = 2.0, y = 2.1, r = 3.9}
Line 1,497 ⟶ 1,770:
This is a translation of the Java version. [[File:Apollonius-unicon.png|thumb|Solution for Apollonius]]
<
record circle(x,y,r)
Line 1,564 ⟶ 1,837:
ys := P + Q * rs
return circle(xs,ys,rs)
end</
Output:<pre>Circle(x,y,r) := (0, 0, 1)
Line 1,574 ⟶ 1,847:
=={{header|J}}==
'''Solution'''
<
NB.*apollonius v solves Apollonius problems
Line 1,592 ⟶ 1,865:
avg=. +/ % #
(, avg@dist) soln
)</
'''Usage'''
<
0 0 1
4 0 1
Line 1,602 ⟶ 1,875:
2 0.83333333 1.1666667
2 2.1 3.9
</syntaxhighlight>
=={{header|Java}}==
<
{
public double[] center;
Line 1,697 ⟶ 1,970:
System.out.println(solveApollonius(c1,c2,c3,-1,-1,-1));
}
}</
=={{header|jq}}==
{{trans|Go}}
{{works with|jq|1.4}}
<
{"x": .[0], "y": .[1], "r": .[2]};
Line 1,752 ⟶ 2,025:
| [$m + ($n*$rs), $p + ($q*$rs), $rs]
| circle
;</
'''The task''':
<
([0, 0, 1] | circle) as $c1
| ([4, 0, 1] | circle) as $c2
Line 1,760 ⟶ 2,033:
| ( ap($c1; $c2; $c3; true), # interior
ap($c1; $c2; $c3; false) ) # exterior
;</
{{Out}}
<
{"x":2,"y":0.8333333333333333,"r":1.1666666666666667}
{"x":2,"y":2.1,"r":3.9}</
=={{header|Julia}}==
Line 1,772 ⟶ 2,045:
'''Module''':
<syntaxhighlight lang
module ApolloniusProblems
using Polynomials, LinearAlgebra, Printf
export Circle
Line 1,813 ⟶ 2,086:
d = (x[1] ^ 2 + y[1] ^ 2 - r[1] ^ 2) .- (x[2:3] .^ 2 .+ y[2:3] .^ 2 .- r[2:3] .^ 2)
end
u =
v =
w =
s = (u - x[1]) ^ 2 + (v - y[1]) ^ 2 - w
r = filter(x -> iszero(imag(x)) && x > zero(x), roots(s))
Line 1,821 ⟶ 2,094:
length(r) == 1 || error("There is no solution.")
r = r[1]
return Circle(
end
end # module ApolloniusProblem</
'''Main''':
<
using .ApolloniusProblems
let test = [Circle(0.0, 0.0, 1.0), Circle(4.0, 0.0, 1.0), Circle(2.0, 4.0, 2.0)]
Line 1,834 ⟶ 2,107:
println("The internal circle is:\n\t", ApolloniusProblems.solve(test))
println("The external circle is:\n\t", ApolloniusProblems.solve(test, 1:3))
end</
{{out}}
Line 1,848 ⟶ 2,121:
=={{header|Kotlin}}==
{{trans|Java}}
<
data class Circle(val x: Double, val y: Double, val r: Double)
Line 1,900 ⟶ 2,173:
println(solveApollonius(c1, c2, c3, 1, 1, 1))
println(solveApollonius(c1, c2, c3,-1,-1,-1))
}</
{{out}}
Line 1,910 ⟶ 2,183:
=={{header|Lasso}}==
{{trans|Java}}
<
local(
x1 = decimal(#c1->get(1)),
Line 1,969 ⟶ 2,242:
solveApollonius((:0, 0, 1), (:4, 0, 1), (:2, 4, 2), 1,1,1)
solveApollonius((:0, 0, 1), (:4, 0, 1), (:2, 4, 2), -1,-1,-1)
</syntaxhighlight>
{{out}}
<pre>staticarray(2.000000, 2.100000, 3.900000)
Line 1,976 ⟶ 2,249:
=={{header|Liberty BASIC}}==
Uses the string Circle$ to hold "xPos, yPos, radius" as csv data. A GUI representation is very easily added.
<syntaxhighlight lang="lb">
circle1$ =" 0.000, 0.000, 1.000"
circle2$ =" 4.000, 0.000, 1.000"
Line 2,031 ⟶ 2,304:
ApolloniusSolver$ =using( "###.###", XPos) +"," +using( "###.###", YPos) +using( "###.###", Radius)
end function
</syntaxhighlight>
x_pos y_pos radius
Line 2,040 ⟶ 2,313:
2.000, 2.100, 3.900
2.000, 0.833, 1.167
=={{header|Lua}}==
<syntaxhighlight lang="lua">
function solveApollonius(x1, y1, r1, x2, y2, r2, x3, y3, r3, s1, s2, s3)
local v11 = 2*x2 - 2*x1
local v12 = 2*y2 - 2*y1
local v13 = x1*x1 - x2*x2 + y1*y1 - y2*y2 - r1*r1 + r2*r2
local v14 = 2*s2*r2 - 2*s1*r1
local v21 = 2*x3 - 2*x2
local v22 = 2*y3 - 2*y2
local v23 = x2*x2 - x3*x3 + y2*y2 - y3*y3 - r2*r2 + r3*r3
local v24 = 2*s3*r3 - 2*s2*r2
local w12 = v12 / v11
local w13 = v13 / v11
local w14 = v14 / v11
local w22 = v22 / v21 - w12
local w23 = v23 / v21 - w13
local w24 = v24 / v21 - w14
local p = -w23 / w22
local q = w24 / w22
local m = -w12*p - w13
local n = w14 - w12*q
local a = n*n + q*q - 1
local b = 2*m*n - 2*n*x1 + 2*p*q - 2*q*y1 + 2*s1*r1
local c = x1*x1 + m*m - 2*m*x1 + p*p + y1*y1 - 2*p*y1 - r1*r1
local d = b*b - 4*a*c
local rs = (-b - math.sqrt(d)) / (2*a)
local xs = m + n*rs
local ys = p + q*rs
return xs, ys, rs
end
</syntaxhighlight>
<syntaxhighlight lang="lua">
-- Example usage
local x1, y1, r1 = 0, 0, 1
local x2, y2, r2 = 4, 0, 1
local x3, y3, r3 = 2, 4, 2
print(solveApollonius(
x1, y1, r1,
x2, y2, r2,
x3, y3, r3,
1, 1, 1
))
print(solveApollonius(
x1, y1, r1,
x2, y2, r2,
x3, y3, r3,
-1, -1, -1
))
--Output:
--2.0 2.1 3.9
--2.0 0.83333333333333 1.1666666666667
</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
Module[{x1=a1,y1=b1,r1=c1,x2=a2,y2=b2,r2=c2,x3=a3,y3=b3,r3=c3,s1=S1,s2=S2,s3=S3},
v11 = 2*x2 - 2*x1; v12 = 2*y2 - 2*y1;
Line 2,068 ⟶ 2,405:
rs = (-b -Sqrt[d])/(2*a);
xs = m + n*rs; ys = p + q*rs;
Map[N,{xs, ys, rs} ]]</
<pre>Apolonius[0,0,1,2,4,2,4,0,1,1,1,1]
Line 2,078 ⟶ 2,415:
=={{header|MUMPS}}==
{{trans|Java}}
<
;Circles are passed in as strings with three parts with a "^" separator in the order x^y^r
;The three circles are CIR1, CIR2, and CIR3
Line 2,119 ⟶ 2,456:
SET $PIECE(CIRR,"^",3)=RS
KILL X1,X2,X3,Y1,Y2,Y3,R1,R2,R3,RS,V11,V12,V13,V14,V21,V22,V23,V24,W12,W13,W14,W22,W23,W24,P,M,N,Q,A,B,C,D
QUIT CIRR</
In use:<pre>
USER>WRITE C1
Line 2,135 ⟶ 2,472:
=={{header|Nim}}==
{{trans|Python}}
<
type Circle = tuple[x, y, r: float]
Line 2,182 ⟶ 2,519:
echo solveApollonius(c1, c2, c3, 1.0, 1.0, 1.0)
echo solveApollonius(c1, c2, c3, -1.0, -1.0, -1.0)</
Output:
<pre>(x: 2.0, y: 2.1, r: 3.9)
Line 2,190 ⟶ 2,527:
{{trans|C}}
<
type circle = {
center: point;
Line 2,265 ⟶ 2,602:
let r2 = solve_apollonius c1 c2 c3 (-1.) (-1.) (-1.) in
print_circle r2;
;;</
=={{header|Perl}}==
Using the module <code>Math::Cartesian::Product</code> to generate the values to allow iteration through all solutions.
{{trans|Raku}}
<
use Math::Cartesian::Product;
Line 2,342 ⟶ 2,679:
for (cartesian {@_} ([-1,1])x3) {
print Circle->show( solve_Apollonius $c1, $c2, $c3, @$_);
}</
{{out}}
<pre>x = 2.000 y = 0.833 r = 1.167
Line 2,354 ⟶ 2,691:
=={{header|Phix}}==
<!--<
<span style="color: #008080;">function</span> <span style="color: #000000;">Apollonius</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">calc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">circles</span><span style="color: #0000FF;">)</span>
Line 2,418 ⟶ 2,755:
<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;">"%d%s solution: x=%+f, y=%+f, r=%f\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">th</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xs</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ys</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rs</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
{{out}}
<pre>
Line 2,432 ⟶ 2,769:
=={{header|PL/I}}==
<
define structure
Line 2,500 ⟶ 2,837:
return (res);
end Solve_Apollonius;
end Apollonius;</
Results:
<pre>
Line 2,508 ⟶ 2,845:
=={{header|PowerShell}}==
{{trans|C#}}
<syntaxhighlight lang="powershell">
function Measure-Apollonius
{
Line 2,578 ⟶ 2,915:
}
}
</syntaxhighlight>
<syntaxhighlight lang="powershell">
for ($i = 1; $i -le 8; $i++)
{
Measure-Apollonius -Counter $i -x1 0 -y1 0 -r1 1 -x2 4 -y2 0 -r2 1 -x3 2 -y3 4 -r3 2
}
</syntaxhighlight>
{{Out}}
<pre>
Line 2,601 ⟶ 2,938:
=={{header|PureBasic}}==
{{trans|Java}}
<
XPos.f
YPos.f
Line 2,674 ⟶ 3,011:
EndIf
Print("Press ENTER to exit"): Input()
EndIf</
<pre>Circle [x=2.00, y=2.10, r=3.90]
Circle [x=2.00, y=0.83, r=1.17]
Line 2,681 ⟶ 3,018:
=={{header|Python}}==
{{trans|Java}}. Although a Circle class is defined, the solveApollonius function is defined in such a way that any three valued tuple or list could be used instead of c1, c2, and c3. The function calls near the end use instances of the Circle class, whereas the docstring shows how the same can be achieved using simple tuples. (And also serves as a simple [[wp:Doctest|doctest]])
<
from collections import namedtuple
import math
Line 2,737 ⟶ 3,074:
c1, c2, c3 = Circle(0, 0, 1), Circle(4, 0, 1), Circle(2, 4, 2)
print(solveApollonius(c1, c2, c3, 1, 1, 1)) #Expects "Circle[x=2.00,y=2.10,r=3.90]" (green circle in image)
print(solveApollonius(c1, c2, c3, -1, -1, -1)) #Expects "Circle[x=2.00,y=0.83,r=1.17]" (red circle in image)</
'''Sample Output'''
<pre>Circle(x=2.0, y=2.1, r=3.9)
Line 2,744 ⟶ 3,081:
=={{header|Racket}}==
{{trans|Java}}
<syntaxhighlight lang="racket">
#lang slideshow
Line 2,829 ⟶ 3,166:
"green" (apollonius c1 c2 c3 1.0 1.0 1.0)
"red" (apollonius c1 c2 c3 -1.0 -1.0 -1.0))
</syntaxhighlight>
=={{header|Raku}}==
Line 2,841 ⟶ 3,178:
Finally, writing in an [https://en.wikipedia.org/wiki/Static_single_assignment_form SSA style] tends to help the optimizer.
<syntaxhighlight lang="raku"
has $.x;
has $.y;
Line 2,890 ⟶ 3,227:
for ([X] [-1,1] xx 3) -> @i {
say (solve-Apollonius @c, @i).gist;
}</
{{out}}
<pre>x = 2.000 y = 0.833 r = 1.167
Line 2,903 ⟶ 3,240:
=={{header|REXX}}==
Programming note: REXX has no '''sqrt''' (square root) function, so a RYO version is included here.
<
/*────────────────────────────────────── Perga [Pergæus] (circa 262 BCE ──► 190 BCE). */
numeric digits 15; x1= 0; y1= 0; r1= 1
Line 2,932 ⟶ 3,269:
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g) * .5; end /*k*/; return g
/*──────────────────────────────────────────────────────────────────────────────────────*/
tell: parse arg _,a b c; w=digits()+4; say _ left(a/1,w%2) left(b/1,w) left(c/1,w); return</
Programming note: in REXX, dividing by unity normalizes the number.
Line 2,944 ⟶ 3,281:
{{trans|Java}}
<
def initialize(x, y, r)
@x, @y, @r = [x, y, r].map(&:to_f)
Line 3,000 ⟶ 3,337:
puts Circle.apollonius(c1, c2, c3)
puts Circle.apollonius(c1, c2, c3, -1, -1, -1)</
{{out}}
Line 3,012 ⟶ 3,349:
=={{header|Scala}}==
<
case class Circle(x: Double, y: Double, r: Double)
object Tangent extends Enumeration {
Line 3,092 ⟶ 3,429:
}
}
}</
Output:
<pre>
Line 3,113 ⟶ 3,450:
=={{header|Sidef}}==
{{trans|Raku}}
<
method to_s { "Circle(#{x}, #{y}, #{r})" }
}
Line 3,160 ⟶ 3,497:
var c = [Circle(0, 0, 1), Circle(4, 0, 1), Circle(2, 4, 2)];
say solve_apollonius(c, %n<1 1 1>);
say solve_apollonius(c, %n<-1 -1 -1>);</
{{out}}
<pre>
Line 3,169 ⟶ 3,506:
=={{header|Swift}}==
{{trans|Java}}
<
struct Circle {
Line 3,240 ⟶ 3,577:
println(solveApollonius(c1,c2,c3,1,1,1).toString())
println(solveApollonius(c1,c2,c3,-1,-1,-1).toString())</
{{out}}
<pre>Circle[x=2.0,y=2.1,r=3.9]
Line 3,248 ⟶ 3,585:
{{trans|Java}}
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
<
oo::class create circle {
Line 3,303 ⟶ 3,640:
return [circle new $xs $ys $rs]
}</
Demonstration code:
<
set c2 [circle new 4 0 1]
set c3 [circle new 2 4 2]
Line 3,311 ⟶ 3,648:
set sB [solveApollonius $c1 $c2 $c3 -1 -1 -1]
puts [$sA format]
puts [$sB format]</
Output:
<pre>
Line 3,323 ⟶ 3,660:
=={{header|VBA}}==
<
Option Explicit
Option Base 0
Line 3,521 ⟶ 3,858:
End Function
</syntaxhighlight>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-dynamic}}
<
var Circle = Tuple.create("Circle", ["x", "y", "r"])
Line 3,581 ⟶ 3,918:
var c3 = Circle.new(2, 4, 2)
System.print("Circle%(solveApollonius.call(c1, c2, c3, 1, 1, 1))")
System.print("Circle%(solveApollonius.call(c1, c2, c3, -1, -1, -1))")</
{{out}}
Line 3,587 ⟶ 3,924:
Circle(2, 2.1, 3.9)
Circle(2, 0.83333333333333, 1.1666666666667)
</pre>
=={{header|XPL0}}==
{{trans|Go}}
<syntaxhighlight lang "XPL0">real Circle(3);
def \Circle\ X, Y, R;
proc real AP(C1, C2, C3, S);
real C1, C2, C3; int S;
real X1sq, Y1sq, R1sq,
X2sq, Y2sq, R2sq,
X3sq, Y3sq, R3sq,
V11, V12, V13, V14,
V21, V22, V23, V24,
W12, W13, W14,
W22, W23, W24,
P, Q, M, N, A, B, C, D, RS;
[
X1sq:= C1(X) * C1(X);
Y1sq:= C1(Y) * C1(Y);
R1sq:= C1(R) * C1(R);
X2sq:= C2(X) * C2(X);
Y2sq:= C2(Y) * C2(Y);
R2sq:= C2(R) * C2(R);
X3sq:= C3(X) * C3(X);
Y3sq:= C3(Y) * C3(Y);
R3sq:= C3(R) * C3(R);
V11:= 2. * (C2(X) - C1(X));
V12:= 2. * (C2(Y) - C1(Y));
V13:= X1sq - X2sq + Y1sq - Y2sq - R1sq + R2sq;
V14:= 2. * (C2(R) - C1(R));
V21:= 2. * (C3(X) - C2(X));
V22:= 2. * (C3(Y) - C2(Y));
V23:= X2sq - X3sq + Y2sq - Y3sq - R2sq + R3sq;
V24:= 2. * (C3(R) - C2(R));
if S then [V14:= -V14; V24:= -V24];
W12:= V12 / V11;
W13:= V13 / V11;
W14:= V14 / V11;
W22:= V22/V21 - W12;
W23:= V23/V21 - W13;
W24:= V24/V21 - W14;
P:= -W23 / W22;
Q:= W24 / W22;
M:= -W12*P - W13;
N:= W14 - W12*Q;
A:= N*N + Q*Q - 1.;
B:= M*N - N*C1(X) + P*Q - Q*C1(Y);
if S then B:= B - C1(R)
else B:= B + C1(R);
B:= B * 2.;
C:= X1sq + M*M - 2.*M*C1(X) + P*P + Y1sq - 2.*P*C1(Y) - R1sq;
D:= B*B - 4.*A*C;
RS:= (-B - sqrt(D)) / (2.*A);
Circle(X):= M + N*RS;
Circle(Y):= P + Q*RS;
Circle(R):= RS;
];
real C1, C2, C3;
[
C1:= [0., 0., 1.];
C2:= [4., 0., 1.];
C3:= [2., 4., 2.];
AP(C1, C2, C3, true);
RlOut(0, Circle(X)); RlOut(0, Circle(Y)); RlOut(0, Circle(R)); CrLf(0);
AP(C1, C2, C3, false);
RlOut(0, Circle(X)); RlOut(0, Circle(Y)); RlOut(0, Circle(R)); CrLf(0);
]</syntaxhighlight>
{{out}}
<pre>
2.00000 0.83333 1.16667
2.00000 2.10000 3.90000
</pre>
=={{header|zkl}}==
{{trans|D}}
<
fcn init(xpos,ypos,radius){
var [const] x=xpos.toFloat(), y=ypos.toFloat(),r=radius.toFloat();
Line 3,632 ⟶ 4,042:
Circle(M + N*rs, P + Q*rs, rs);
}
}</
<
a.apollonius(b,c).println(" Outside");
a.apollonius(b,c,False).println(" Inside");</
{{out}}
<pre>
|