diff options
Diffstat (limited to 'bezier.jl')
| -rw-r--r-- | bezier.jl | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/bezier.jl b/bezier.jl new file mode 100644 index 0000000..7d42746 --- /dev/null +++ b/bezier.jl @@ -0,0 +1,76 @@ +using EzXML + +""" +Get a complex parametric function for a series of cubic bezier curves as described in an .svg file. See README for details on file requirements. +""" +function createCurve(fileName) + doc = readxml(pwd() * "/" * fileName) + + svg = root(doc) + + layers = [] + paths = [] + + for element in eachelement(svg) + occursin("layer", element["id"]) && push!(layers, element) + end + + for element in eachelement(layers[1]) + occursin("path", element["id"]) && push!(paths, element) + end + + pointPattern = r"(?<=c ).*" + curveString = match(pointPattern, paths[1]["d"]).match + + pattern = r"((?:-)?\d*(?:\.\d*)?),((?:-)?\d*(?:\.\d*)?)" + m = collect(eachmatch(pattern, curveString)) + + b_input = [[0.0,0.0]] + + for i in m + k = length(b_input) + Δx = parse(Float64, i[1]) + Δy = -parse(Float64, i[2]) + new_point = [b_input[k-(k-1)%3][1] + Δx, b_input[k-(k-1)%3][2] + Δy] + + push!(b_input, new_point) + end + + return t -> parametricBezier(t, b_input) +end + +""" +Parametric function for a curve made up of cubic bezier curves described by a vector of complex coordinates `input`. + +Format for points taken from svg format. +""" +function parametricBezier(t, input) + t = t%1 + n_input = length(input)-1 + n_cubics = n_input÷3 + + cubicIndex = convert(Int, t÷(1//n_cubics)+1) + cubicTime = (t%(1/n_cubics))*n_cubics + currentCubic = input[3(cubicIndex-1)+1:3cubicIndex+1] + b_t = b(cubicTime, currentCubic) + + return b_t[1] + b_t[2]*im +end + +""" +Get position along bezier curve described by points `p` at time `t` from 0 to 1. +""" +function b(t, p) + s = [0,0] + + for i in 1:length(p) + s += B(length(p)-1,i-1,t) * p[i] + end + + return s +end + +"Bernstein polynomial" +function B(n_p,i,t) + binomial(n_p,i)*t^i*(1-t)^(n_p-i) +end
\ No newline at end of file |