1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| #!/usr/bin/env python
# -*- coding:Utf-8 -*-
import math
import cmath
import cairo
#------ Configuration --------
IMAGE_SIZE = (1000, 1000)
NUM_SUBDIVISIONS = 5
#-----------------------------
goldenRatio = (1 + math.sqrt(5)) / 2
def subdivide(triangles):
result = []
for color, A, B, C in triangles:
if color == 0:
# Subdivide red triangle
P = A + (B - A) / goldenRatio
result += [(0, C, P, B), (1, P, C, A)]
else:
# Subdivide blue triangle
Q = B + (A - B) / goldenRatio
R = B + (C - B) / goldenRatio
result += [(1, R, C, A), (1, Q, R, B), (0, R, Q, A)]
return result
def penrose( filename, color1, color2):
# Create wheel of red triangles around the origin
triangles = []
for i in xrange(10):
B = cmath.rect(1, (2*i - 1) * math.pi / 10)
C = cmath.rect(1, (2*i + 1) * math.pi / 10)
if i % 2 == 0:
B, C = C, B # Make sure to mirror every second triangle
triangles.append((0, 0j, B, C))
# Perform subdivisions
for i in xrange(NUM_SUBDIVISIONS):
triangles = subdivide(triangles)
# Prepare cairo surface
surface = cairo.PDFSurface(filename, IMAGE_SIZE[0], IMAGE_SIZE[1])
cr = cairo.Context(surface)
cr.translate(IMAGE_SIZE[0] / 2.0, IMAGE_SIZE[1] / 2.0)
wheelRadius = 1.2 * math.sqrt((IMAGE_SIZE[0] / 2.0) ** 2 + (IMAGE_SIZE[1] / 2.0) ** 2)
cr.scale(wheelRadius, wheelRadius)
# Draw red triangles
for color, A, B, C in triangles:
if color == 0:
cr.move_to(A.real, A.imag)
cr.line_to(B.real, B.imag)
cr.line_to(C.real, C.imag)
cr.close_path()
red, green, blue = color1
cr.set_source_rgb( red, green, blue)
cr.fill()
# Draw blue triangles
for color, A, B, C in triangles:
if color == 1:
cr.move_to(A.real, A.imag)
cr.line_to(B.real, B.imag)
cr.line_to(C.real, C.imag)
cr.close_path()
red, green, blue = color2
cr.set_source_rgb( red, green, blue)
cr.fill()
# Determine line width from size of first triangle
color, A, B, C = triangles[0]
cr.set_line_width(abs(B - A) / 10.0)
cr.set_line_join(cairo.LINE_JOIN_ROUND)
# Draw outlines
for color, A, B, C in triangles:
cr.move_to(C.real, C.imag)
cr.line_to(A.real, A.imag)
cr.line_to(B.real, B.imag)
cr.set_source_rgb( 0.2, 0.2, 0.2)
cr.stroke()
if __name__ == '__main__':
filename = 'penrose.pdf'
# Couleurs RGB
color1 = 1.0, 0.35, 0.35
color2 = 0.4, 0.4, 1.0
penrose( filename, color1, color2) |
Partager