To be able to edit code and run cells, you need to run the notebook yourself. Where would you like to run the notebook?

This notebook takes about 1 minute to run.

In the cloud (experimental)

Binder is a free, open source service that runs scientific notebooks in the cloud! It will take a while, usually 2-7 minutes to get a session.

On your computer

(Recommended if you want to store your changes.)

  1. Copy the notebook URL:
  2. Run Pluto

    (Also see: How to install Julia and Pluto)

  3. Paste URL in the Open box

Frontmatter

If you are publishing this notebook on the web, you can set the parameters below to provide HTML metadata. This is useful for search engines and social media.

Author 1
3×2 Matrix{Float64}:
 0.0  0.0
 1.0  0.0
 0.0  1.0
👀 Reading hidden code
points = [
0.0 0
1.0 0
0.0 1
]
25.6 ms
👀 Reading hidden code
Enter cell code...
67.4 μs
👀 Reading hidden code
begin
import Pkg
eval(quote
Pkg.add(url="https://github.com/paulgb/PenPlots.jl")
end)
using PenPlots
end
❔
    Updating git-repo `https://github.com/paulgb/PenPlots.jl`
    Updating registry at `~/.julia/registries/General.toml`
   Resolving package versions...
    Updating `/tmp/jl_fsPfSI/Project.toml`
  [61246389] ~ PenPlots v0.1.0 `https://github.com/paulgb/PenPlots.jl#master` ⇒ v0.1.0 `https://github.com/paulgb/PenPlots.jl#master`
    Updating `/tmp/jl_fsPfSI/Manifest.toml`
  [61246389] ~ PenPlots v0.1.0 `https://github.com/paulgb/PenPlots.jl#master` ⇒ v0.1.0 `https://github.com/paulgb/PenPlots.jl#master`
12.2 s
👀 Reading hidden code
using Triangulate
1.8 ms
👀 Reading hidden code
let n=10,raster=10
triin=Triangulate.TriangulateIO()
triin.pointlist=hcat(unique([ Cdouble[rand(1:raster)/raster, rand(1:raster)/raster] for i in 1:n])...)
display(triin)
(triout, vorout)=Triangulate.triangulate("Q", triin)
end
❔
TriangulateIO(
pointlist=[0.2 0.3 … 0.7 1.0; 1.0 1.0 … 0.3 0.6],
)
907 ms
2×10 Matrix{Float64}:
 0.9  0.6  0.2  0.2  0.6  0.2  1.0  1.0  1.0  0.1
 0.1  0.8  1.0  0.5  0.5  0.6  0.9  0.7  0.5  0.3
let n=10,raster=10
hcat(unique([ Cdouble[rand(1:raster)/raster, rand(1:raster)/raster] for i in 1:n])...)
end
👀 Reading hidden code
48.1 ms
to_triangulate_mat (generic function with 1 method)
function to_triangulate_mat(ps::AbstractVector{<:SVector})
# const output_type = eltype(eltype(ps))
# output_type = Float64
A = Matrix{Float64}(undef, length(eltype(ps)), length(ps))
for (i,p) in enumerate(ps)
@inbounds A[:,i] .= p
end
A
end
👀 Reading hidden code
1.5 ms
2×10 Matrix{Float64}:
 0.160801   0.500827  0.875971  0.414216  …  0.359395  0.550349  0.973304
 0.0767157  0.750534  0.24558   0.389123     0.857727  0.209442  0.00825298
aa = rand(2,10)
👀 Reading hidden code
16.0 μs
Error message

MethodError: no method matching reinterpret(::Int64, ::Type{StaticArrays.SVector{Float64, 2}}, ::Matrix{Float64})

Closest candidates are:

reinterpret(::typeof(reshape), ::Type{T}, ::A) where {T, S, A<:(AbstractArray{S})} at /opt/hostedtoolcache/julia/1.7.3/x64/share/julia/base/reinterpretarray.jl:52

reinterpret(::typeof(reshape), ::Type{T}, ::Base.ReinterpretArray{T, N, S, A, true} where {T, N, S, A<:(AbstractArray{S})}) where T at /opt/hostedtoolcache/julia/1.7.3/x64/share/julia/base/reinterpretarray.jl:124

reinterpret(::typeof(reshape), ::Type{T}, ::AbstractArray{T}) where T at /opt/hostedtoolcache/julia/1.7.3/x64/share/julia/base/reinterpretarray.jl:78

...

Stack trace

Here is what happened, the most recent locations are first:

  1. reinterpret(10, SVector{Float64,2}, aa)
reinterpret(10, SVector{Float64,2}, aa)
👀 Reading hidden code
---
triangulate_raw (generic function with 1 method)
function triangulate_raw(ps::AbstractVector{<:SVector}; switches::String="Q")
mat = to_triangulate_mat(ps)
triin=Triangulate.TriangulateIO()
triin.pointlist=mat
Triangulate.triangulate(switches, triin)
end
👀 Reading hidden code
1.9 ms
TriangulateIO(
pointlist=[-28.606110189574423 -33.27986187595284 … 196.3870134493292 200.0; 25.593153555170787 22.911509651021046 … -25.06274838429784 -9.797174393178826e-14],
pointmarkerlist=Int32[0, 0, 0, 0, 0, 0, 0, 0, 0, 0  …  1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
trianglelist=Int32[62 64 … 30 19; 13 15 … 78 1; 61 63 … 79 18],
)
triangulate_raw(xx; switches="Q")[1]
👀 Reading hidden code
307 ms
triangulate (generic function with 1 method)
function triangulate(args...; kwargs...)
t, v = triangulate_raw(args...; kwargs...)

z = t.trianglelist
[
SVector{4,Int}(z[1,j], z[2,j], z[3,j], z[1,j] )
for j in 1:size(z,2)
]
end
👀 Reading hidden code
2.3 ms
"nothingasdf"
string(nothing, "asdf")
👀 Reading hidden code
15.6 ms
"100.000000000000000"
@sprintf("%.15f",100)
👀 Reading hidden code
64.0 μs
n (generic function with 1 method)
n(prefix::String, value::Float64) = "$(prefix)$(@sprintf("%.15f",value))"
👀 Reading hidden code
4.9 ms
n (generic function with 2 methods)
n(prefix::String, value::Bool) = prefix
👀 Reading hidden code
378 μs
n (generic function with 3 methods)
n(prefix::String, value::Nothing) = ""
👀 Reading hidden code
403 μs
# let n=10,raster=10
# triin=Triangulate.TriangulateIO()
# triin.pointlist=hcat(unique([ Cdouble[rand(1:raster)/raster, rand(1:raster)/raster] for i in 1:n])...)
# display(triin)
# Triangulate.triangulate("Qa38.986q18.986037025490717", triin)[1].trianglelist
# end
👀 Reading hidden code
8.7 μs
build_switches (generic function with 1 method)
function build_switches(;
max_area::Union{Float64,Nothing}=nothing,
min_angle::Union{Float64,Nothing}=nothing,
quiet::Bool=true,
)
@assert isnothing(min_angle) || min_angle < 28.6 "Oh ohhh"

string(
n("Q", quiet),
n("a", max_area),
n("q", min_angle),
)
end
👀 Reading hidden code
2.2 ms
triangulate_true (generic function with 1 method)
function triangulate_true(args...; kwargs...)
t, v = triangulate_raw(args...; switches=build_switches(;kwargs...))

pl = t.pointlist
new_pl = [
SVector{2,Float64}(pl[1,j], pl[2,j] )
for j in 1:size(pl,2)
]
tl = t.trianglelist
new_tl = [
SVector{4,Int}(tl[1,j], tl[2,j], tl[3,j], tl[1,j] )
for j in 1:size(tl,2)
]
new_pl, new_tl
end
👀 Reading hidden code
3.8 ms
using HypertextLiteral
👀 Reading hidden code
4.3 ms
using CoordinateTransformations
👀 Reading hidden code
7.4 ms
using Rotations
👀 Reading hidden code
137 μs
@label_bind (macro with 1 method)
👀 Reading hidden code
637 μs
max_area:
👀 Reading hidden code
774 ms
min_angle:
👀 Reading hidden code
146 ms
result = let
pl, tl = triangulate_true(xx; max_area, min_angle)
[
without_duplicate_lines([
Path(pl[t])
for t in tl
])...,
[
Path(200 .* (degree_rotation(rand(0:359)),) .* (small_dot.points) .+ (x,))
for x in xx
]...,
]
end
👀 Reading hidden code
941 ms

👀 Reading hidden code
68.5 μs
xx = [10000*SVector(p...) for p in small_dot.points[20:end]]
👀 Reading hidden code
81.2 ms

👀 Reading hidden code
66.9 μs
# xx = 10 .* randn(SVector{2,Float64},20)
👀 Reading hidden code
8.5 μs
split_lines

Split a Path into the single-line paths that it consists of, but check the return type...

"Split a `Path` into the single-line paths that it consists of, but check the return type..."
split_lines(p::Path)::Vector{Tuple{Point,Point}} = [
# Use `extrema` to "sort" the two points (which just works apparently!). This will canonalize the result.
extrema((p.points[i], p.points[i+1]))
for i in 1:length(p.points)-1
]
👀 Reading hidden code
1.6 ms
using BenchmarkTools
👀 Reading hidden code
85.8 ms
without_duplicate_lines (generic function with 1 method)
function without_duplicate_lines(paths::MultiPath)::MultiPath
original_lines = flatmap(split_lines, paths)
unique_lines = Set(original_lines)

sort([Path([l...]) for l in unique_lines])
end
👀 Reading hidden code
1.0 ms
16434
without_duplicate_lines(result) .|> length |> sum
👀 Reading hidden code
77.1 ms
8496
result .|> length |> sum
👀 Reading hidden code
34.5 μs
flatmap (generic function with 1 method)
flatmap(args...) = vcat(map(args...)...)
👀 Reading hidden code
466 μs

👀 Reading hidden code
61.1 μs
using PlutoUI
👀 Reading hidden code
278 ms
using Printf
👀 Reading hidden code
131 μs
random_subset (generic function with 1 method)
random_subset(xs) = xs[rand(Bool, length(xs))]
👀 Reading hidden code
419 μs
[
[
Path(xx[t])
for t in triangulate(xx; switches="Q")
]...,
[
Path(small_dot.points .+ (x,))
for x in xx
]...,
]
👀 Reading hidden code
242 ms
small_triangle = Path([
SVector(-.1, -.1),
SVector(0, .07),
SVector(.1, -.1),
SVector(-.1, -.1),
] .* .2)
👀 Reading hidden code
199 ms
small_dot = Path([
0.01 * x * SVector(cos(x*2π), sin(x*2π))
for x in LinRange(0,2,100)
])
👀 Reading hidden code
269 ms
xx
👀 Reading hidden code
9.0 μs
triangulate_raw(xx; switches="QiC")
👀 Reading hidden code
113 μs
using StaticArrays
👀 Reading hidden code
159 μs

👀 Reading hidden code
60.7 μs