fractalcurves.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #!/usr/bin/env python3
  2. """ turtle-example-suite:
  3. tdemo_fractalCurves.py
  4. This program draws two fractal-curve-designs:
  5. (1) A hilbert curve (in a box)
  6. (2) A combination of Koch-curves.
  7. The CurvesTurtle class and the fractal-curve-
  8. methods are taken from the PythonCard example
  9. scripts for turtle-graphics.
  10. """
  11. from turtle import *
  12. from time import sleep, perf_counter as clock
  13. class CurvesTurtle(Pen):
  14. # example derived from
  15. # Turtle Geometry: The Computer as a Medium for Exploring Mathematics
  16. # by Harold Abelson and Andrea diSessa
  17. # p. 96-98
  18. def hilbert(self, size, level, parity):
  19. if level == 0:
  20. return
  21. # rotate and draw first subcurve with opposite parity to big curve
  22. self.left(parity * 90)
  23. self.hilbert(size, level - 1, -parity)
  24. # interface to and draw second subcurve with same parity as big curve
  25. self.forward(size)
  26. self.right(parity * 90)
  27. self.hilbert(size, level - 1, parity)
  28. # third subcurve
  29. self.forward(size)
  30. self.hilbert(size, level - 1, parity)
  31. # fourth subcurve
  32. self.right(parity * 90)
  33. self.forward(size)
  34. self.hilbert(size, level - 1, -parity)
  35. # a final turn is needed to make the turtle
  36. # end up facing outward from the large square
  37. self.left(parity * 90)
  38. # Visual Modeling with Logo: A Structural Approach to Seeing
  39. # by James Clayson
  40. # Koch curve, after Helge von Koch who introduced this geometric figure in 1904
  41. # p. 146
  42. def fractalgon(self, n, rad, lev, dir):
  43. import math
  44. # if dir = 1 turn outward
  45. # if dir = -1 turn inward
  46. edge = 2 * rad * math.sin(math.pi / n)
  47. self.pu()
  48. self.fd(rad)
  49. self.pd()
  50. self.rt(180 - (90 * (n - 2) / n))
  51. for i in range(n):
  52. self.fractal(edge, lev, dir)
  53. self.rt(360 / n)
  54. self.lt(180 - (90 * (n - 2) / n))
  55. self.pu()
  56. self.bk(rad)
  57. self.pd()
  58. # p. 146
  59. def fractal(self, dist, depth, dir):
  60. if depth < 1:
  61. self.fd(dist)
  62. return
  63. self.fractal(dist / 3, depth - 1, dir)
  64. self.lt(60 * dir)
  65. self.fractal(dist / 3, depth - 1, dir)
  66. self.rt(120 * dir)
  67. self.fractal(dist / 3, depth - 1, dir)
  68. self.lt(60 * dir)
  69. self.fractal(dist / 3, depth - 1, dir)
  70. def main():
  71. ft = CurvesTurtle()
  72. ft.reset()
  73. ft.speed(0)
  74. ft.ht()
  75. ft.getscreen().tracer(1,0)
  76. ft.pu()
  77. size = 6
  78. ft.setpos(-33*size, -32*size)
  79. ft.pd()
  80. ta=clock()
  81. ft.fillcolor("red")
  82. ft.begin_fill()
  83. ft.fd(size)
  84. ft.hilbert(size, 6, 1)
  85. # frame
  86. ft.fd(size)
  87. for i in range(3):
  88. ft.lt(90)
  89. ft.fd(size*(64+i%2))
  90. ft.pu()
  91. for i in range(2):
  92. ft.fd(size)
  93. ft.rt(90)
  94. ft.pd()
  95. for i in range(4):
  96. ft.fd(size*(66+i%2))
  97. ft.rt(90)
  98. ft.end_fill()
  99. tb=clock()
  100. res = "Hilbert: %.2fsec. " % (tb-ta)
  101. sleep(3)
  102. ft.reset()
  103. ft.speed(0)
  104. ft.ht()
  105. ft.getscreen().tracer(1,0)
  106. ta=clock()
  107. ft.color("black", "blue")
  108. ft.begin_fill()
  109. ft.fractalgon(3, 250, 4, 1)
  110. ft.end_fill()
  111. ft.begin_fill()
  112. ft.color("red")
  113. ft.fractalgon(3, 200, 4, -1)
  114. ft.end_fill()
  115. tb=clock()
  116. res += "Koch: %.2fsec." % (tb-ta)
  117. return res
  118. if __name__ == '__main__':
  119. msg = main()
  120. print(msg)
  121. mainloop()