June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -0,0 +1,51 @@
module ApolloniusProblems
using Polynomials
export Circle
struct Point{T<:Real}
x::T
y::T
end
xcoord(p::Point) = p.x
ycoord(p::Point) = p.y
struct Circle{T<:Real}
c::Point{T}
r::T
end
Circle(x::T, y::T, r::T) where T<:Real = Circle(Point(x, y), r)
radius(c::Circle) = c.r
center(c::Circle) = c.c
xcenter(c::Circle) = xcoord(center(c))
ycenter(c::Circle) = ycoord(center(c))
Base.show(io::IO, c::Circle) =
@printf(io, "centered at (%0.4f, %0.4f) with radius %0.4f",
xcenter(c), ycenter(c), radius(c))
function solve(ap::Vector{Circle{T}}, enc=()) where T<:Real
length(ap) == 3 || error("This Apollonius problem needs 3 circles.")
x = @. xcenter(ap)
y = @. ycenter(ap)
r = map(u -> ifelse(u ∈ enc, -1, 1), 1:3) .* radius.(ap)
@views begin
a = 2x[1] .- 2x[2:3]
b = 2y[1] .- 2y[2:3]
c = 2r[1] .- 2r[2:3]
d = (x[1] ^ 2 + y[1] ^ 2 - r[1] ^ 2) .- (x[2:3] .^ 2 .+ y[2:3] .^ 2 .- r[2:3] .^ 2)
end
u = Poly([-det([b d]), det([b c])] ./ det([a b]))
v = Poly([det([a d]), -det([a c])] ./ det([a b]))
w = Poly([r[1], 1.0]) ^ 2
s = (u - x[1]) ^ 2 + (v - y[1]) ^ 2 - w
r = filter(x -> iszero(imag(x)) && x > zero(x), roots(s))
length(r) < 2 || error("The solution is not unique.")
length(r) == 1 || error("There is no solution.")
r = r[1]
return Circle(polyval(u, r), polyval(v, r), r)
end
end # module ApolloniusProblem

View file

@ -0,0 +1,8 @@
include("module.jl")
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)]
println("The defining circles are: \n - ", join(test, "\n - "))
println("The internal circle is:\n\t", ApolloniusProblems.solve(test))
println("The external circle is:\n\t", ApolloniusProblems.solve(test, 1:3))
end

View file

@ -1,55 +0,0 @@
using Polynomials
immutable Point{T<:Real}
x::T
y::T
end
immutable Circle{T<:Real}
c::Point{T}
r::T
end
Circle{T<:Real}(x::T, y::T, r::T) = Circle(Point(x,y), r)
function apollonius{T<:Real}(ap::Array{Circle{T},1},
enc::Array{Int,1}=Int[])
length(ap) == 3 || error("This Apollonius problem needs 3 circles.")
x = map(u->u.c.x, ap)
y = map(u->u.c.y, ap)
r = map(u->u in enc ? -1 : 1, 1:3) .* map(u->u.r, ap)
a = 2x[1] - 2x[2:3]
b = 2y[1] - 2y[2:3]
c = 2r[1] - 2r[2:3]
d = (x[1]^2 + y[1]^2 - r[1]^2)
d -= (map(u->u^2, x) + map(u->u^2, y) - map(u->u^2, r))[2:3]
u = Poly([-det(hcat(b,d)), det(hcat(b,c))]/det(hcat(a,b)))
v = Poly([det(hcat(a,d)), -det(hcat(a,c))]/det(hcat(a,b)))
w = Poly([r[1], 1.0])^2
s = (u - x[1])^2 + (v - y[1])^2 - w
r = filter(x->imag(x)==0 && 0<x, roots(s))
length(r) < 2 || error("The solution is not unique.")
length(r) == 1 || error("There is no solution.")
r = r[1]
Circle(polyval(u,r), polyval(v,r), r)
end
function detail(c::Circle)
x = @sprintf "%.4f" c.c.x
y = @sprintf "%.4f" c.c.y
r = @sprintf "%.4f" c.r
@sprintf "centered at (%s, %s) with radius %s" x y r
end
test = [Circle(0.,0.,1.),
Circle(4.,0.,1.),
Circle(2.,4.,2.)]
println("The defining circles are:")
for c in test
println(" ", detail(c))
end
println("The internal circle is:")
println(" ", detail(apollonius(test)))
println("The external circle is:")
println(" ", detail(apollonius(test, [1:3])))