"""
Barnsley fractal fern
Copyright David Joyner wdjoyner@gmail.com, 2008.
Licensed under the creative commons Attribution 3.0 license,
http://creativecommons.org/licenses/by/3.0/us/
"""
def f(i,P):
'''
Returns image under one of four coordinate mapping functions.
'''
x = P[0]
y = P[1]
if i==0:
return [ 0.65*x + 0.04*y - 0.10, -0.01*x + 0.65*y + 1.60]
if i==1:
return [-0.15*x + 0.28*y + 0.10, 0.26*x + 0.24*y + 0.44]
if i==2:
return [0.20*x - 0.26*y - 0.10, 0.23*x + 0.22*y + 0.60]
if i==3:
return [-0.10*x + 0.20*y + 0.10, 0.00*x + 0.26*y + 1.50]
def fern_leaf(num_pts, clr, pt_size=2, initial_pt = (0,0), center_pt = (0,0)):
"""
Returns a graphics objects with num_pts randomly plotted points
in the rgb color, clr, of size pt_size, with initial point initial_pt,
"centered" at center_pt.
EXAMPLES:
sage: P1 = fern_leaf(20000, (0,0.95,0.3))
sage: P2a = fern_leaf(1, (0.9, 0.1, 0), pt_size=50, center_pt=(-0.7,2))
sage: P2b = fern_leaf(2, (0.9, 0.1, 0.5), pt_size=50, center_pt=(1.2,4))
sage: P2c = fern_leaf(2, (0.9, 0.1, 0), pt_size=50, center_pt=(0.3,3.4))
sage: P2d = fern_leaf(2, (0.9, 0.1, 0), pt_size=50, center_pt=(0.25,4.7))
sage: P3 = fern_leaf(2, (0.7, 0.1, 0.2), pt_size=80, center_pt=(1.4,5))
sage: P4a = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=80, center_pt=(1.5,3))
sage: P4b = fern_leaf(2, (0.9, 0.1, 0.6), pt_size=80, center_pt=(1.2,2.8))
sage: P4c = fern_leaf(1, (0.9, 0.1, 0.7), pt_size=80, center_pt=(-0.9,3))
sage: P5a = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=10, center_pt=(1.0,5.8))
sage: P5b = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=10, center_pt=(1.2,5.5))
sage: P5c = fern_leaf(2, (0.9, 0.1, 0.2), pt_size=10, center_pt=(1.5,4.8))
sage: (P2a+P2b+P2c+P2d+P3+P4a+P4b+P4c+P1+P5a+P5b+P5c).show(axes=False)
Here P1 is the branch or tree and P2-P5 are berries or ornaments:-).
"""
p0 = 0.01 # prob pick f0
p1 = 0.07 # prob pick f1
p2 = 0.07 # prob pick f2
p3 = 0.85 # prob pick f3
#p = [p0,1,p2,p3]
P = initial_pt
pts = [P]
for i in range(num_pts):
r = random()
#print i, r
if 0<r<p0:
P = tuple(f(3,P))
pts.append(P)
elif p0<r<p0+p1:
P = tuple(f(1,P))
pts.append(P)
elif p0+p1<r<p0+p1+p2:
P = tuple(f(2,P))
pts.append(P)
else:
P = tuple(f(0,P))
pts.append(P)
if center_pt != (0,0):
pts_centered = [center_pt]
for p in pts:
pts_centered.append((p[0]+center_pt[0],p[1]+center_pt[1]))
else:
pts_centered = pts
return point(pts_centered,rgbcolor=clr, axes=False, pointsize=pt_size)
def f_2008_12_5(i,P):
'''
One of four coordinate mapping functions.
'''
x = P[0]
y = P[1]
if i==0:
return [ 0.85*x + 0.04*y - 0.01, -0.04*x + 0.85*y + 1.60]
if i==1:
return [-0.15*x + 0.28*y + 0.01, 0.26*x + 0.24*y + 0.44]
if i==2:
return [0.20*x - 0.26*y - 0.01, 0.23*x + 0.22*y + 0.60]
if i==3:
return [-0.10*x + 0.20*y + 0.01, 0.00*x + 0.26*y + 1.50]
def f_2008_12_6(i,P):
'''
One of four coordinate mapping functions.
'''
x = P[0]
y = P[1]
if i==0:
return [ 0.85*x + 0.07*y - 0.10, -0.1*x + 0.85*y + 1.60]
if i==1:
return [-0.15*x + 0.28*y + 0.10, 0.26*x + 0.24*y + 0.44]
if i==2:
return [0.20*x - 0.26*y - 0.10, 0.23*x + 0.22*y + 0.60]
if i==3:
return [-0.10*x + 0.20*y + 0.10, 0.00*x + 0.26*y + 1.50]
def f_spikey(i,P):
'''
One of four coordinate mapping functions.
'''
x = P[0]
y = P[1]
if i==0:
return [ 0.45*x + 0.07*y - 0.10, -0.1*x + 0.85*y + 1.60]
if i==1:
return [-0.15*x + 0.28*y + 0.10, 0.26*x + 0.24*y + 0.44]
if i==2:
return [0.20*x - 0.26*y - 0.10, 0.23*x + 0.22*y + 0.60]
if i==3:
return [-0.10*x + 0.20*y + 0.10, 0.00*x + 0.26*y + 1.50]