Skip to content

Instantly share code, notes, and snippets.

@cormullion
Last active November 22, 2021 22:48
Show Gist options
  • Save cormullion/e979d819e478da73280faaeb67490888 to your computer and use it in GitHub Desktop.
Save cormullion/e979d819e478da73280faaeb67490888 to your computer and use it in GitHub Desktop.
pi digits
#!/usr/bin/env julia
using Luxor
function pidigits(n)
result = Int[]
k, a::BigInt, b::BigInt, a1::BigInt, b1::BigInt = 2, 4, 1, 12, 4
while n > 0
p, q, k = k * k, 2k + 1, k + 1
a, b, a1, b1 = a1, b1, p * a + q * a1, p * b + q * b1
d, d1 = div(a, b), div(a1, b1)
while (d == d1) && (n > 0)
push!(result, d)
n -= 1
a, a1 = 10 * (a % b), 10 * (a1 % b1)
d, d1 = div(a, b), div(a1, b1)
end
end
return result
end
function drawjulia()
gsave()
scale(2, 2)
translate(-165, -120)
sethue("grey80")
setopacity(0.4)
julialogo(color=false)
grestore()
end
function draw()
Drawing(1000, 500, "/tmp/pi.png")
background("royalblue4")
origin()
drawjulia()
fontface("Georgia-Bold")
tiles = Tiler(1000, 500, 50, 100, margin=5)
thedigitsofpi = pidigits(50 * 100)
fontsize(10)
setopacity(0.8)
setline(0.25)
for (pos, n) in tiles
sethue(0.7, rand(), rand(0.0:0.1:0.4))
thedigit = thedigitsofpi[n]
n == 1 && text(string(thedigit, "."), pos, halign=:center) # dat decimal point doe
n > 1 && text(string(thedigit), pos, halign=:center)
end
finish()
preview()
end
draw()
@cormullion
Copy link
Author

pi

@cormullion
Copy link
Author

pi

@cormullion
Copy link
Author

#!/usr/bin/env julia

using Luxor

function textcurve1(the_text, start_angle, start_radius, x_pos=0, y_pos=0;
    spiral_ring_step = 0,
    letter_spacing = 0,
    spiral_in_out_shift = 0,
    clockwise = true,
    f = 12
    )
    refangle = start_angle
    current_radius = start_radius
    spiral_space_step = 0
    xx = 0
    yy = 0
    angle_step = 0
    radius_step = 0
    for i in the_text
        f = max(.1, f-0.0025)
        fontsize(f)
        glyph = string(i)
        glyph_x_bearing, glyph_y_bearing, glyph_width,
        glyph_height, glyph_x_advance, glyph_y_advance = textextents(glyph)
        spiral_space_step = glyph_x_advance + letter_spacing
        cnter = (2pi * current_radius) / spiral_space_step
        radius_step = (spiral_ring_step + spiral_in_out_shift) / cnter
        current_radius += radius_step
        angle_step += (glyph_x_advance / 2.0) + letter_spacing/2.0
        if clockwise
            refangle += angle_step / current_radius
        else
            refangle -= angle_step / current_radius
        end
        angle_step = (glyph_x_advance / 2.0) + letter_spacing/2.0
        xx = cos(refangle) * current_radius + x_pos
        yy = sin(refangle) * current_radius + y_pos
        gsave()
        translate(xx, yy)
        if clockwise
            rotate(pi/2 + refangle)
        else
            rotate(-pi/2 + refangle)
        end
        textcentred(glyph, 0, 0)
        grestore()
        current_radius < 1 && break
    end
end

function pidigits(n)
    result = Int[]
    k, a::BigInt, b::BigInt, a1::BigInt, b1::BigInt = 2, 4, 1, 12, 4
    while n > 0
        p, q, k = k * k, 2k + 1, k + 1
        a, b, a1, b1 = a1, b1, p * a + q * a1, p * b + q * b1
        d, d1 = a ÷ b, a1 ÷ b1
        while (d == d1) && (n > 0)
            push!(result, d)
            n -= 1
            a, a1 = 10(a % b), 10(a1 % b1)
            d, d1 = a ÷ b, a1 ÷ b1
        end
    end
    return result
end

function drawjulia()
    gsave()
    scale(2, 2)
    translate(-165, -120)
    sethue("grey80")
    setopacity(0.3)
    julialogo(color=false)
    grestore()
end

function draw(width, height, fsize)
    Drawing(width, height, "/tmp/pi.pdf")
    digitwords = ["oh", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
    background("ivory")
    origin()

    gsave()
    setopacity(0.3)
    sethue("grey30")
    fontface("Times-Bold")
    fontsize(800)
    text("π", halign=:center, valign=:middle)
    grestore()

    fontface("Georgia-Bold")
    thedigitsofpi = pidigits(500)
    fontsize(fsize)
    setline(0.25)
    n = 1
    margin = 20
    x = -width/2 + margin
    y = -height/2 + margin
    while y < height/2 && n < 10000
        thedigit = thedigitsofpi[n]
        sethue("grey10")
        if n == 1
            s = string("π is ", digitwords[thedigit + 1], " point")
        end
        sethue(rand(0.5:0.1:0.8), rand(0.1:0.1:0.5), 0.2)
        n > 1 && (s = digitwords[thedigit + 1])
        s = s * " "
        text(s, x, y)
        se = textextents(s)
        x += se[5]

        if n % 100 == 0
            gsave()
            fontsize(0.75fsize)
            fontface("Helvetica")
            sethue("black")
            text(string("[", n, "]"), x, y)
            se = textextents(string("[", n, "]"))
            grestore()
            x += se[5]
        end

        if x > width/2 - margin - se[5]/2
            x = -width/2 + margin
            y += fsize + 1
        end
        n += 1
    end
    finish()
    preview()
end

function spiraldraw(width, height, fsize)
    Drawing(width+25, height+25, "/tmp/pi.pdf")
    digitwords = ["oh", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
    background("ivory")
    origin()

    gsave()
    setopacity(0.2)
    sethue("grey30")
    fontface("Times-Bold")
    fontsize(800)
    text("π", halign=:center, valign=:middle)
    grestore()

    fontface("Menlo-Bold")
    fontsize(fsize)
    setline(0.25)

    s = map(n -> digitwords[n+1], collect(pidigits(8000)))
    s = string("π is ", s[1], " point ", join(s[2:end], " "))
    sethue("purple")
    textcurve1(s,
        -pi/2,
        width/2 - 15, 0, 0,
        spiral_in_out_shift = -15,
        letter_spacing = 0,
        spiral_ring_step = 0,
        f=fsize)

    finish()
    preview()
end

spiraldraw(800, 800, 16)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment