Skip to content

Instantly share code, notes, and snippets.

@vegard
Created September 21, 2018 07:51
Show Gist options
  • Save vegard/ed66c215223fee77d8ffc0181093525e to your computer and use it in GitHub Desktop.
Save vegard/ed66c215223fee77d8ffc0181093525e to your computer and use it in GitHub Desktop.
Prime factorisation diagram
# -*- coding: utf-8 -*-
#
# Author: Vegard Nossum <[email protected]>
import math
import os
import sys
import cairo
w = 7
h = 7
# https://stackoverflow.com/a/22808285/1697183
def prime_factors(n):
i = 2
factors = []
while i * i <= n:
if n % i:
i += 1
else:
n //= i
factors.append(i)
if n > 1:
factors.append(n)
return factors
def fours(n):
factors = []
while n % 4 == 0:
factors.append(4)
n //= 4
return factors + prime_factors(n)
# https://math.stackexchange.com/a/1806107/179367
def r(n):
s = math.sin(math.pi / n)
return s / (s + 1)
out_w, out_h = 128 * w, 128 * h
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, out_w, out_h)
cr = cairo.Context(surface)
cr.set_line_width(0)
cr.set_source_rgb(1, 1, 1)
cr.rectangle(0, 0, out_w, out_h)
cr.fill()
def draw(factors):
if not factors:
cr.arc(0.0, 0.0, 1.0, 0.0, 2.0 * math.pi)
cr.fill()
return
n = factors[0]
if n == 4:
cr.rotate(-math.pi / 4)
for i in range(n):
cr.save()
cr.rotate(2.0 * math.pi * i / n)
cr.translate(1.0, 0)
cr.scale(0.95 * r(n), 0.95 * r(n))
draw(factors[1:])
cr.restore()
cr.set_source_rgba(.5, 0, 0, 1)
for y in range(h):
for x in range(w):
cr.save()
cr.translate(1. * (.5 + x) * out_w / w, 1. * (.5 + y) * out_h / h)
cr.scale(28.0, 28.0)
cr.rotate(-math.pi / 2)
number = 1 + y * w + x
factors = list(reversed(fours(number)))
draw(factors)
cr.restore()
surface.write_to_png('output.png')
@vegard
Copy link
Author

vegard commented Sep 21, 2018

Output:
output

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