Skip to content

Commit

Permalink
Update vSystem.py
Browse files Browse the repository at this point in the history
Added comments.
  • Loading branch information
psweens committed Apr 14, 2023
1 parent 2141129 commit 23dded8
Showing 1 changed file with 206 additions and 59 deletions.
265 changes: 206 additions & 59 deletions vSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,122 +5,269 @@
from analyseGrammar import posneg

def I(n, d0, val=3):
'''
A recursive function to generate an "I" fractal pattern.
Args:
n (int): the level of recursion. n = 0 returns "I".
d0 (float): the initial length of the line segment.
val (int, optional): a constant used in the function. Default is 3.
Returns:
str: the resulting string representing the fractal pattern.
'''
if n > 0:
# Calculate parameters for bifurcation and string formation
params = calBifurcation(d0)
p1 = calParam(str.join('co/',str(int(val))), params)
p1 = calParam(str.join('co/', str(int(val))), params)

# Add a random rotation to the new line segment
rotate = np.random.uniform(22.5, 27.5)

# Recursive call to generate the string for the next level
return 'f(' + p1 + ',' + str(params['d0']) + ')' + '+(' + str(rotate) + ')' +\
'[' + R(n-1, params['d0']) + ']'
else: return 'I'
'[' + I(n-1, params['d0']) + ']'
else:
# Base case: return "I"
return 'I'


def R(n, d0):
if n > 0:
params = calBifurcation(d0)
p1 = calParam(str.join('co/',str(int(3))), params)
p2 = calParam(str.join('co/',str(int(2))), params)
descrip = 'f(' + p1 + ')' + G(n, d0, val=7) +\
G(n-1, d0, val=7) + G(n-1, d0, val=7) + '[' + B(n-1, params['d1']) +\
']' + 'f(' + p2 + ',' + str(params['d2']) + ')' + B(n-1, params['d2'])
return descrip
else: return 'R'
'''
A recursive function to generate an "R" fractal pattern.
Parameters:
- n (int): The level of recursion. Must be a non-negative integer.
- d0 (float): The diameter of the parent branch. Must be a positive float.
Returns:
- A string description of a bifurcating tree.
'''
if n == 0:
return 'R'

params = calBifurcation(d0) # Calculates bifurcation parameters based on parent diameter
p1 = calParam('co/' + str(int(3)), params) # Calculates the parameters for the first child branch
p2 = calParam('co/' + str(int(2)), params) # Calculates the parameters for the second child branch

# Calls G function recursively to generate descriptions of child branches
# The descriptions are concatenated with function calls and brackets to form the final description
descrip = 'f(' + p1 + ')' + G(n, d0, val=7) + G(n-1, d0, val=7) + G(n-1, d0, val=7) \
+ '[' + B(n-1, params['d1']) + ']' \
+ 'f(' + p2 + ',' + str(params['d2']) + ')' + B(n-1, params['d2'])

return descrip



def B(n, d0):
"""
A recursive function to generate an "B" fractal pattern.
Args:
- n (int): The current bifurcation level.
- d0 (float): The current diameter of the parent branch.
Returns:
- A string describing the bifurcation structure.
Raises:
- N/A
"""

if n > 0:
return G(n-1, d0, val=7) + G(n-1, d0, val=7) + G(n-1, d0, val=7) +\
'/(' +str(90.0) + ')' + A(n, d0)
else: return 'B'
# Recursively generate descriptions of child branches
descrip = G(n-1, d0, val=7) + G(n-1, d0, val=7) + G(n-1, d0, val=7) +\
'/(' +str(90.0) + ')' + A(n, d0)
return descrip
else:
# Return string representation of parent branch
return 'B'


def F(n, d0):
"""
A recursive function to generate an "F" fractal pattern.
Args:
- n (int): number of iterations to perform
- d0 (float): the initial distance
Returns:
- str: a string of characters representing the fractal generated by the given parameters.
"""
if n > 0:
# calculate the bifurcation parameters
params = calBifurcation(d0)
theta1 = params['th1'] #+ np.random.uniform(-2.5, 2.5)
theta2 = params['th2'] #+ np.random.uniform(-2.5, 2.5)
tilt = np.random.uniform(22.5, 27.5)*random.randint(-1,1)
return S(n-1, d0)+'['+'+('+str(theta1)+')'+'/('+str(tilt)+')'+\
F(n-1, params['d1'])+']'+'['+'-('+str(theta2)+')'+'/('+str(tilt)+')'+\
F(n-1, params['d2'])+']'
else: return 'F'

# calculate the angles for rotation and tilt
theta1 = params['th1']
theta2 = params['th2']
tilt = np.random.uniform(22.5, 27.5) * random.randint(-1, 1)

# recursively generate the fractal string using the calculated parameters
return S(n-1, d0) + '[' + '+(' + str(theta1) + ')/(' + str(tilt) + ')' + \
F(n-1, params['d1']) + ']' + '[' + '-(' + str(theta2) + ')/(' + str(tilt) + ')' + \
F(n-1, params['d2']) + ']'
else:
# return the base character if n <= 0
return 'F'


def S(n, d0, val=5, margin=0.5):
"""
S function generates the shape of a tree's stem.
Args:
n (int): The depth of the recursive algorithm.
d0 (float): The trunk diameter of the tree.
val (int, optional): Default is 5. The angle in degrees between a branch and the trunk.
margin (float, optional): Default is 0.5. The chance of using one of two sub-functions (S1, S2) to generate the stem.
Returns:
str: A string representing the shape of a tree's stem.
"""
# Check if the depth of the recursion is greater than zero
if n <= 0:
return 'S'

# Generate a random number between 0 and 1
r = random.random()
if r>= 0.0 and r < margin: return '{' + S1(n, d0, val) + '}'
if r >= margin and r < 1.0: return '{' + S2(n, d0, val) + '}'

# Determine which sub-function to use based on the random number and margin value
if r >= 0.0 and r < margin:
return '{' + S1(n, d0, val) + '}'
if r >= margin and r < 1.0:
return '{' + S2(n, d0, val) + '}'


def S1(n, d0, val=5):
if n>0:
# "Fanning" of trees
rotate = np.random.uniform(22.5, 27.5)*random.randint(-1,1)
"""
Recursive function that generates a string representation of a tree structure.
Args:
- n (int): the recursion level, i.e. the number of times the function is called recursively.
- d0 (float): the initial diameter of the tree.
- val (int): value to be passed to function D(). Default value is 5.
Returns:
- str: string representation of a tree structure.
"""
if n > 0:
# Randomly rotate the branches of the tree
rotate = np.random.uniform(22.5, 27.5) * random.randint(-1, 1)
params = calBifurcation(d0)
descrip = D(n-1, params['d0'], val) + '+(' + str(rotate) + ')' + \
D(n-1, params['d0'], val) + '-(' + str(rotate) + ')' + \
D(n-1, params['d0'], val) + '-(' + str(rotate) + ')' + \
D(n-1, params['d0'], val) + '+(' + str(rotate)+ ')' + \
D(n-1, params['d0'], val)
D(n-1, params['d0'], val) + '-(' + str(rotate) + ')' + \
D(n-1, params['d0'], val) + '+(' + str(rotate)+ ')' + \
D(n-1, params['d0'], val)
return descrip
else: return 'S'
else:
return 'S'


def S2(n, d0, val=5):
if n>0:
"""
Recursive function that generates a string representation of a tree structure.
Parameters:
n (int): the level of recursion. Controls the depth of the tree-like structure.
d0 (float): the trunk diameter of the tree at the base.
val (int): the numerical value to assign to the final string. Default value is 5.
Returns:
descrip (str): the final string representation of the tree-like structure.
"""
if n > 0:
# "Fanning" of trees
rotate = np.random.uniform(22.5, 27.5)*random.randint(-1,1)
rotate = np.random.uniform(22.5, 27.5) * random.randint(-1, 1)
params = calBifurcation(d0)
descrip = D(n-1, params['d0'], val) + '-(' + str(rotate) + ')' + \
D(n-1, params['d0'], val) + '+(' + str(rotate) + ')' + \
D(n-1, params['d0'], val) + '+(' + str(rotate) + ')' + \
D(n-1, params['d0'], val) + '-(' + str(rotate) + ')' + \
D(n-1, params['d0'], val)
return descrip
else: return 'S'
else:
return 'S'


def D(n, d0, val=5):
if n>0:
"""
Generate a string of L-system symbols for generating a fractal tree using a
deterministic context-free Lindenmayer system (D0L-system) with production rules.
Parameters:
n (int): Number of iterations.
d0 (float): Starting diameter of the tree.
val (int): Value to be passed to `calParam` function (default is 5).
Returns:
str: The generated L-system symbols string for the fractal tree.
"""
if n > 0:
# Calculate the parameters for the bifurcation of the tree
params = calBifurcation(d0)
p1 = calParam(str.join('co/',str(int(val))), params)

# Calculate the parameter for the function call
p1 = calParam(str.join('co/', str(int(val))), params)

# Return the L-system string with the calculated parameters
return 'f(' + p1 + ',' + str(params['d0']) + ')'
else: return 'D'
else:
# If the number of iterations is 0, return the symbol 'D'
return 'D'


def G(n, d0, val=5, shift=18.0):
if n>0:
"""
Generates a string representing the result of the function f with parameters p1 and d0.
Args:
- n (int): number of iterations of the function f.
- d0 (float): parameter d0 of the bifurcation function.
- val (int): value to use for calculating the parameter p1. Default is 5.
- shift (float): value to add to the result of f. Default is 18.0.
Returns:
- str: a string representing the result of the function f with parameters p1 and d0.
"""
if n > 0:
params = calBifurcation(d0)
p1 = calParam(str.join('co/',str(int(val))), params)
return 'f(' + p1 + ',' + str(params['d0']) + ')'
else: return 'G'
p1 = calParam(str.join('co/', str(int(val))), params)
# Call function f with parameters p1 and d0, and add the value of shift to the result
return str(float(f(p1, params['d0'])) + shift)
else:
return 'G'


def A(n, d0):
"""
Generates string description of fractal tree using recursive approach
Args:
n (int): Depth of the recursion
d0 (float): Initial branch length
Returns:
str: String description of the fractal tree
"""
if n > 0:
# calculate bifurcation angles and branch lengths
params = calBifurcation(d0)
return S(n-1, d0) + '[+(' + str(params['th1']) + ')' + A(n-1, params['d1']) + ']' +\
'[+(' + str(params['th2']) + ')' + A(n-1, params['d2'])
else: return 'A'


# def A(d0):
# return 'f(' + str(1) + ',' + str(d0) + ')' + 'f(' + str(1) + ',' + str(2*d0) + ')' + \
# 'f(' + str(1) + ',' + str(d0) + ')'
# recursive calls to A and S functions
return (
S(n-1, d0)
+ '[+(' + str(params['th1']) + ')' + A(n-1, params['d1']) + ']'
+ '[+(' + str(params['th2']) + ')' + A(n-1, params['d2']) + ']'
)
else:
return 'A'

# def E(d0):
# return 'f(' + str(1) + ',' + str(d0) + ')' + 'f(' + str(1) + ',' + str(0.5*d0) + ')' + \
# 'f(' + str(1) + ',' + str(d0) + ')'











# 2D grammars - don't currently work with framework
def simplest_gramma(n=None, theta1=20., theta2=20., params=None):
return 'f' + '[' + '+' + F(n-1, params['d0']) + ']' + '-' + F(n-1, params['d0'])
Expand Down

0 comments on commit 23dded8

Please sign in to comment.