Python 再说勾股树,这次整一棵五彩的任意“生长”的分形树!
Posted Hann Yang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 再说勾股树,这次整一棵五彩的任意“生长”的分形树!相关的知识,希望对你有一定的参考价值。
上一篇《Turtle库画一棵对称勾股树,美丽惊艳的分形世界!》中描绘了一棵对称的双色勾股树,详情见:Python Turtle库画一棵对称勾股树,美丽惊艳的分形世界!_汉阳Hann's Home-CSDN博客 分形,具有以非整数维形式充填空间的形态特征。通常被定义为“一个粗糙或零碎的几何形状,可以分成数个部分,且每一部分都(至少近似地)是整体缩小后的形状”,即具有自相似的性质。分形(Fractal)一词,是芒德勃罗创造出来的,其原意具有不规则、支离破碎等意义。1973年,芒德勃罗(B.B.Mandelbrot)在法兰西学院讲课时,首次提出了分维和分形的设想。 分形是一个数学术语,也是一套以分形特征为研究主题的数学理论。分形理论既是非线性科学的前沿和重要分支,又是一门新兴的横断学科,是研究一类现象特征的新.https://blog.csdn.net/boysoft2002/article/details/120466255
修改一
简单的,加上一随机取色的函数,就能画出彩色树来。颜色取值方法有很多,常用的如下:
方法一:随机产生一个6位十六进制数
>>> from random import choice
>>> def rndColor():
color,strColor = '#','0123456789ABCDEF'
for _ in range(6):
color += choice(strColor)
return color
>>> print([rndColor() for _ in range(7)])
['#47922E', '#540621', '#AEA706', '#263CAC', '#2F346E', '#067BAC', '#4D295B']
>>>
方法二:在给定预定义颜色单词中取值,颜色数相对少但也够用
>>> def rndColor():
from random import choice
colors = ('black', 'navy', 'darkblue', 'mediumblue', 'blue', 'darkgreen', 'green',
'teal', 'darkcyan', 'deepskyblue', 'darkturquoise', 'mediumspringgreen', 'lime',
'springgreen', 'aqua', 'cyan', 'midnightblue', 'dodgerblue', 'lightseagreen',
'forestgreen', 'seagreen', 'darkslategray', 'limegreen', 'mediumseagreen', 'turquoise',
'royalblue', 'steelblue', 'darkslateblue', 'mediumturquoise', 'indigo', 'darkolivegreen',
'cadetblue', 'cornflowerblue', 'mediumaquamarine', 'dimgray', 'slateblue', 'olivedrab',
'slategray', 'lightslategray', 'mediumslateblue', 'lawngreen', 'chartreuse',
'aquamarine', 'maroon', 'purple', 'olive', 'gray', 'skyblue', 'lightskyblue',
'blueviolet', 'darkred', 'darkmagenta', 'saddlebrown', 'darkseagreen', 'lightgreen',
'mediumpurple', 'darkviolet', 'palegreen', 'darkorchid', 'yellowgreen', 'sienna',
'brown', 'darkgray', 'lightblue', 'greenyellow', 'paleturquoise', 'lightsteelblue',
'powderblue', 'firebrick', 'darkgoldenrod', 'mediumorchid', 'rosybrown', 'darkkhaki',
'silver', 'mediumvioletred', 'indianred', 'peru', 'chocolate', 'tan', 'lightgray',
'thistle', 'orchid', 'goldenrod', 'palevioletred', 'crimson', 'gainsboro', 'plum',
'burlywood', 'lightcyan', 'lavender', 'darksalmon', 'violet', 'palegoldenrod',
'lightcoral', 'khaki', 'aliceblue', 'honeydew', 'azure', 'wheat', 'beige', 'whitesmoke',
'mintcream', 'ghostwhite', 'salmon', 'sandybrown', 'antiquewhite', 'linen',
'lightgoldenrodyellow', 'oldlace', 'red', 'fuchsia', 'magenta', 'deeppink', 'orangered',
'tomato', 'hotpink', 'coral', 'darkorange', 'lightsalmon', 'orange', 'lightpink',
'pink', 'gold', 'peachpuff', 'navajowhite', 'moccasin', 'bisque', 'mistyrose',
'blanchedalmond', 'papayawhip', 'lavenderblush', 'seashell', 'cornsilk', 'lemonchiffon',
'floralwhite', 'snow', 'yellow', 'lightyellow', 'ivory', 'white')
return choice(colors)
>>> print([rndColor() for _ in range(7)])
['whitesmoke', 'dodgerblue', 'sandybrown', 'wheat', 'mediumorchid', 'goldenrod', 'tan']
>>> print([rndColor() for _ in range(7)])
['darkblue', 'slateblue', 'aliceblue', 'salmon', 'seashell', 'darkgray', 'bisque']
>>>
就用方法一来取色,上一篇中的对称勾股树经填色后,效果如下:
源代码如下,填色语句已用#号注释掉了(效果上图左上):
from turtle import *
from random import choice
def rndColor():
color,strColor = '#','0123456789ABCDEF'
for _ in range(6):
color += choice(strColor)
return color
def Square(self,length):
self.color(rndColor())
#self.begin_fill()
for _ in range(5):
self.forward(length)
self.right(90)
#self.end_fill()
def Triangle(self,length):
self.color(rndColor())
#self.begin_fill()
self.left(45)
self.forward(length/2**0.5)
self.right(90)
self.forward(length/2**0.5)
self.right(135)
self.forward(length)
#self.end_fill()
def Move2Right(self,length):
self.back(length)
self.right(45)
self.forward(length/2**0.5)
self.right(90)
def Recursive(n, tracer, length):
if n<1: return
tracers = []
for left in tracer:
left.pencolor(rndColor())
Square(left, length)
Triangle(left, length)
right = left.clone()
left.right(45)
Move2Right(right, length)
tracers.append(left)
tracers.append(right)
Recursive(n-1, tracers, length/2**0.5)
def Setup(self, length, speed):
self.hideturtle()
self.speed(speed)
self.penup()
self.goto(-length*0.5, -length*1.8)
self.seth(90)
self.pensize(2)
self.pendown()
def main(level, length, speed=-1):
setup(800,600)
title('Fractal Tree')
if speed==-1: tracer(0)
else: tracer(1)
t = Turtle()
Setup(t, length, speed)
from time import sleep
sleep(2)
Recursive(level, list([t]), length)
done()
bye()
if __name__ == '__main__':
main(9,135,-1)
修改二
左右偏向角都是45度勾股树就是对称的,那么角度指定从列表[i for i in range(5,86)]中抽取,勾股树的“树枝”就能任意角度生长了。参考网上的代码,增加了 onclick 事件,这样就可以反复观察效果。类似于 tkinter 库中用 .bind(<事件>,方法) 绑定函数来增加对象的事件动作,当然turtle窗口中也能使用bind方法(之后再作研究讨论)。经过修改后效果如下:
源代码如下:
import turtle
from random import choice
from math import sin,cos,radians
def rndColor(flag=True):
colorTuple=(
('navy', '#000080'),
('darkblue', '#00008B'),
('mediumblue', '#0000CD'),
('blue', '#0000FF'),
('darkgreen', '#006400'),
('green', '#008000'),
('teal', '#008080'),
('darkcyan', '#008B8B'),
('deepskyblue', '#00BFFF'),
('darkturquoise', '#00CED1'),
('mediumspringgreen', '#00FA9A'),
('lime', '#00FF00'),
('springgreen', '#00FF7F'),
('aqua', '#00FFFF'),
('cyan', '#00FFFF'),
('midnightblue', '#191970'),
('dodgerblue', '#1E90FF'),
('lightseagreen', '#20B2AA'),
('forestgreen', '#228B22'),
('seagreen', '#2E8B57'),
('darkslategray', '#2F4F4F'),
('limegreen', '#32CD32'),
('mediumseagreen', '#3CB371'),
('turquoise', '#40E0D0'),
('royalblue', '#4169E1'),
('steelblue', '#4682B4'),
('darkslateblue', '#483D8B'),
('mediumturquoise', '#48D1CC'),
('indigo', '#4B0082'),
('darkolivegreen', '#556B2F'),
('cadetblue', '#5F9EA0'),
('cornflowerblue', '#6495ED'),
('mediumaquamarine', '#66CDAA'),
('dimgray', '#696969'),
('slateblue', '#6A5ACD'),
('olivedrab', '#6B8E23'),
('slategray', '#708090'),
('lightslategray', '#778899'),
('mediumslateblue', '#7B68EE'),
('lawngreen', '#7CFC00'),
('chartreuse', '#7FFF00'),
('aquamarine', '#7FFFD4'),
('maroon', '#800000'),
('purple', '#800080'),
('olive', '#808000'),
('gray', '#808080'),
('skyblue', '#87CEEB'),
('lightskyblue', '#87CEFA'),
('blueviolet', '#8A2BE2'),
('darkred', '#8B0000'),
('darkmagenta', '#8B008B'),
('saddlebrown', '#8B4513'),
('darkseagreen', '#8FBC8F'),
('lightgreen', '#90EE90'),
('mediumpurple', '#9370DB'),
('darkviolet', '#9400D3'),
('palegreen', '#98FB98'),
('darkorchid', '#9932CC'),
('yellowgreen', '#9ACD32'),
('sienna', '#A0522D'),
('brown', '#A52A2A'),
('darkgray', '#A9A9A9'),
('lightblue', '#ADD8E6'),
('greenyellow', '#ADFF2F'),
('paleturquoise', '#AFEEEE'),
('lightsteelblue', '#B0C4DE'),
('powderblue', '#B0E0E6'),
('firebrick', '#B22222'),
('darkgoldenrod', '#B8860B'),
('mediumorchid', '#BA55D3'),
('rosybrown', '#BC8F8F'),
('darkkhaki', '#BDB76B'),
('silver', '#C0C0C0'),
('mediumvioletred', '#C71585'),
('indianred', '#CD5C5C'),
('peru', '#CD853F'),
('chocolate', '#D2691E'),
('tan', '#D2B48C'),
('lightgray', '#D3D3D3'),
('thistle', '#D8BFD8'),
('orchid', '#DA70D6'),
('goldenrod', '#DAA520'),
('palevioletred', '#DB7093'),
('crimson', '#DC143C'),
('gainsboro', '#DCDCDC'),
('plum', '#DDA0DD'),
('burlywood', '#DEB887'),
('lightcyan', '#E0FFFF'),
('lavender', '#E6E6FA'),
('darksalmon', '#E9967A'),
('violet', '#EE82EE'),
('palegoldenrod', '#EEE8AA'),
('lightcoral', '#F08080'),
('khaki', '#F0E68C'),
('aliceblue', '#F0F8FF'),
('honeydew', '#F0FFF0'),
('azure', '#F0FFFF'),
('wheat', '#F5DEB3'),
('beige', '#F5F5DC'),
('whitesmoke', '#F5F5F5'),
('mintcream', '#F5FFFA'),
('ghostwhite', '#F8F8FF'),
('salmon', '#FA8072'),
('sandybrown', '#FAA460'),
('antiquewhite', '#FAEBD7'),
('linen', '#FAF0E6'),
('lightgoldenrodyellow', '#FAFAD2'),
('oldlace', '#FDF5E6'),
('red', '#FF0000'),
('fuchsia', '#FF00FF'),
('magenta', '#FF00FF'),
('deeppink', '#FF1493'),
('orangered', '#FF4500'),
('tomato', '#FF6347'),
('hotpink', '#FF69B4'),
('coral', '#FF7F50'),
('darkorange', '#FF8C00'),
('lightsalmon', '#FFA07A'),
('orange', '#FFA500'),
('lightpink', '#FFB6C1'),
('pink', '#FFC0CB'),
('gold', '#FFD700'),
('peachpuff', '#FFDAB9'),
('navajowhite', '#FFDEAD'),
('moccasin', '#FFE4B5'),
('bisque', '#FFE4C4'),
('mistyrose', '#FFE4E1'),
('blanchedalmond', '#FFEBCD'),
('papayawhip', '#FFEFD5'),
('lavenderblush', '#FFF0F5'),
('seashell', '#FFF5EE'),
('cornsilk', '#FFF8DC'),
('lemonchiffon', '#FFFACD'),
('floralwhite', '#FFFAF0'),
('snow', '#FFFAFA'),
('yellow', '#FFFF00'),
('lightyellow', '#FFFFE0'),
('ivory', '#FFFFF0'),
) # 已去掉black和white
color,strColor = '#','0123456789ABCD' #去掉EF调节颜色
for _ in range(6): color += choice(strColor)
if flag: return color
return choice(colorTuple)[1]
def Square(length):
t.color(rndColor()) # 参数改为Flase换colorTuple中的颜色
t.begin_fill()
for i in range(4):
t.fd(length)
t.right(90)
t.end_fill()
def biTree(length):
if length<0.08*Length: return
xy = t.position()
if abs(xy[0])>Width/2-2*length: return
if xy[1]>Half_H-length*3: return
if xy[1]<-Half_H+length*0.5: return
# 以上四行尽可能约束树枝不超出可视范围
Square(length)
Angle = choice([i for i in range(5,86)]) #左右偏向角度,不宜过大或过小
t.forward(length)
t.left(Angle)
biTree(length * cos(radians(Angle)))
Square(length * cos(radians(Angle)))
t.right(90)
t.forward(length * cos(radians(Angle)))
biTree(length * sin(radians(Angle)))
Square(length * sin(radians(Angle)))
t.right(90)
t.forward(length * sin(radians(Angle)))
t.right(Angle)
t.forward(length)
t.right(90)
t.forward(length)
t.right(90)
def main(x=None,y=None):
x,y = -Half_L, Half_L-Half_H
t.clear()
t.up()
t.goto(x,y)
t.down()
#t.pensize(2)
t.setheading(90)
biTree(Length)
t.penup()
t.goto(Length*0.8,-Half_H+Half_L)
t.pencolor('red')
t.write("Click to refresh......")
t.hideturtle()
if __name__ == '__main__':
Width,Height = 1200,800 #屏幕宽高
Length = 100 #第一层正方形的边长
Half_L,Half_H = Length/2,Height/2
turtle.setup(Width,Height)
turtle.title('随机勾股树')
turtle.tracer(0)
t = turtle.Turtle()
#t.speed(0)
main()
ts = turtle.Screen()
ts.onclick(main)
turtle.mainloop()
代码执行后,不停点击屏幕的动态效果如下:
本篇完!
以上是关于Python 再说勾股树,这次整一棵五彩的任意“生长”的分形树!的主要内容,如果未能解决你的问题,请参考以下文章