pi = 3.1415926

def lrepeat(num,l):
  res = []
  for i in range(num):
    res.extend(l)
  return res
def lcat(la,lb):
  la.extend(lb)
  return la

def b_straight(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h', 
         ['e','lf','h']
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_fork1_2d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h',                                 
         lcat(lrepeat(repeat,['e',['br','h']]),['lf','h'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['br',[
          ['s',branch_scale,lenscale],['rU',branch_angle],['rS',- (p1 - 0.5) * pi]
   ]],
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_fork1_3d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h',                                 
         lcat(lrepeat(repeat,['e',['br','h']]),['lf','h'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['br',[
          ['s',branch_scale,lenscale],['rS',- (p1 - 0.5) * pi],['rF',-pi * 0.5],['rS',-branch_angle]
   ]],
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_split2_2d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h', 
         lcat(lrepeat(repeat,['e','cr',['br','h2'],['bl','h2']]),['lf'])
   ],
   ['h2', 
         lcat(lrepeat(repeat,['e','cl',['br','h'],['bl','h']]),['lf'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['br',[
          ['s',branch_scale,lenscale],['rU',branch_angle]
   ]],
   ['bl',[
          ['s',branch_scale,lenscale],['rU',-branch_angle]
   ]],
   ['cr',[
          ['rU',(p1 - 0.5)  * pi]
   ]],
   ['cl',[
          ['rU',-(p1 - 0.5)  * pi]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_split2_3d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h', 
         lcat(lrepeat(repeat,['e',['br','h'],['bl','h']]),['lf'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['br',[
          ['s',branch_scale,lenscale],['rF',pi * 0.5],['rS',branch_angle],['rS',- (p1 - 0.5) * pi]
   ]],
   ['bl',[
          ['s',branch_scale,lenscale],['rF',pi * -0.5],['rS',branch_angle],['rS',  (p1 - 0.5)  * pi]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_fork1_alt_2d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 rep_half = repeat / 2
 rep_odd = repeat % 2
 if rep_odd:
   grow_rules = [
     ['h',  
           lcat(lrepeat(rep_half,['e',['bl','h'],'e',['br','h']]),['e',['bl','h'],'lf','h2'])
     ],
     ['h2',
           lcat(lrepeat(rep_half,['e',['br','h'],'e',['bl','h']]),['e',['br','h'],'lf','h'])
     ],
     ['lf', []
     ],
 ]
 else:
   grow_rules = [
     ['h',  
           lcat(lrepeat(rep_half,['e',['bl','h'],'e',['br','h']]),['lf','h'])
     ],
     ['lf', []
     ],
 ]
 terminal_rules = [
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['br',[
          ['s',branch_scale,lenscale],['rU',branch_angle],['rS',- (p1 - 0.5) * pi]
   ]],
   ['bl',[
          ['s',branch_scale,lenscale],['rU',-branch_angle],['rS',- (p1 - 0.5)  * pi]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_fork1_alt_3d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 rep_half = repeat / 2
 rep_odd = repeat % 2
 if rep_odd:
   grow_rules = [
     ['h',  
           lcat(lrepeat(rep_half,['e',['bl','h'],'e',['br','h']]),['e',['bl','h'],'lf','h2'])
     ],
     ['h2',  
           lcat(lrepeat(rep_half,['e',['br','h'],'e',['bl','h']]),['e',['br','h'],'lf','h'])
     ],
     ['lf', []
     ],
 ]
 else:
   grow_rules = [
     ['h',  
           lcat(lrepeat(rep_half,['e',['bl','h'],'e',['br','h']]),['lf','h'])
     ],
     ['lf', []
     ],
 ]
 terminal_rules = [
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['br',[
          ['s',branch_scale,lenscale],['rF',pi * 0.5],['rS',branch_angle],['rF',- (p1 - 0.5) * pi]
   ]],
   ['bl',[
          ['s',branch_scale,lenscale],['rF',pi * -0.5],['rS',branch_angle],['rF',- (p1 - 0.5)  * pi]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_fork2_2d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h',  
         lcat(lrepeat(repeat,['e',['br','h'],['bl','h']]),['lf','h'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['br',[
          ['s',branch_scale,lenscale],['rU',branch_angle],['rS',- (p1 - 0.5) * pi]
   ]],
   ['bl',[
          ['s',branch_scale,lenscale],['rU',-branch_angle],['rS',- (p1 - 0.5)  * pi]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_fork2_alt(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 rep_half = repeat / 2
 rep_odd = repeat % 2
 if rep_odd:
   grow_rules = [
     ['h',  
           lcat(lrepeat(rep_half,['e',['bl','h'],['br','h'],'e',['d','bl','h'],['d','br','h']]),['e',['bl','h'],['br','h'],'lf','h2'])
     ],
     ['h2',  
           lcat(lrepeat(rep_half,['e',['d','bl','h'],['d','br','h'],'e',['bl','h'],['br','h']]),['e',['d','bl','h'],['d','br','h'],'lf','h'])
     ],
     ['lf', []
     ],
 ]
 else:
   grow_rules = [
     ['h',  
           lcat(lrepeat(rep_half,['e',['bl','h'],['br','h'],'e',['d','bl','h'],['d','br','h']]),['lf','h'])
     ],
     ['lf', []
     ],
 ]
 terminal_rules = [
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['d',[
          ['rF',pi * 0.5]
   ]],
   ['br',[
          ['s',branch_scale,lenscale],['rS',- (p1 - 0.5) * pi],['rF',-pi * 0.5],['rS',-branch_angle]
   ]],
   ['bl',[
          ['s',branch_scale,lenscale],['rS',- (p1 - 0.5)  * pi],['rF',pi * 0.5],['rS',-branch_angle]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]

def b_fork2_3d(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h',
         lcat(lrepeat(repeat,['e',['br','h'],['bl','h']]),['lf','h'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['a',[
          ['rS',1.5]
   ]],
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['br',[
          ['s',branch_scale,lenscale],['rS',- (p1 - 0.5) * pi],['rF',-pi * 0.5],['rS',-branch_angle]
   ]],
   ['bl',[
          ['s',branch_scale,lenscale],['rS',- (p1 - 0.5)  * pi],['rF',pi * 0.5],['rS',-branch_angle]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]


def b_fork3(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h',  
         lcat(lrepeat(repeat,['e',['c','b','h'],['c','d','b','h'],['c','d','d','b','h']]),['lf','h'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['b',[
          ['s',branch_scale,lenscale],['rS',branch_angle]
   ]],
   ['c',[
          ['rU',(p1 - 0.5) * pi]
   ]],
   ['d',[
          ['rF',0.66666 * pi]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]


def b_split3(repeat,rotF,curve,length,branch_scale,lenscale,branch_angle,resolutionV,p1):
 grow_rules = [
   ['h',  
         lcat(lrepeat(repeat,['e',['c','b','h'],['c','d','b','h'],['c','d','d','b','h']]),['lf'])
   ],
   ['lf', []
   ],
 ]
 terminal_rules = [
   ['g',
          lrepeat(resolutionV,[['a',(length / resolutionV)],['rS',curve],['rF',rotF]])
   ],
   ['a',[
          ['rS',pi * 0.5]
   ]],
   ['b',[
          ['s',branch_scale,lenscale],['rS',branch_angle]
   ]],
   ['c',[
          ['rU',(p1 - 0.5) * pi]
   ]],
   ['d',[
          ['rF',0.66666 * pi]
   ]]
 ]
 axiom = ['a','h']
 return [axiom,grow_rules,terminal_rules]



