# LSystems (travelling salesman) in py5

**URL:** <https://discourse.processing.org/t/lsystems-travelling-salesman-in-py5/32255>\
**Category:** Gallery\
**Created:** [September 14, 2021, 7:00pm UTC](https://discourse.processing.org/t/lsystems-travelling-salesman-in-py5/32255 "2021-09-14T19:00:16Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![monkstone](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/monkstone/32/64_2.png) [@monkstone](https://discourse.processing.org/u/monkstone)\
**Post date:** [September 14, 2021, 7:00pm UTC](https://discourse.processing.org/t/lsystems-travelling-salesman-in-py5/32255/1 "2021-09-14T19:00:16Z")

</div>

Here is a sketch I recently converted from processing.py to py5 (also for me an exploration of NamedTuple) could easily be adapted with other LSystem rules.

```python
import py5
from math import cos, pi, sin, sqrt, radians
from grammar2 import grammar2
from collections import namedtuple

"""
mpeano.py by Martin Prout
LSystem rules from The Euclidean Traveling Salesman Problem.... by MG Norman & P Moscato.
Features a scaling adjustment and turtle reversing, use trignometry rather than processing affine
transforms to calculate the line, uses a grammar module to create production string.
"""

w = 600
h = 600

LSystem = namedtuple('MPeano', 'start, rules, turn_angle_deg')

mpeano = LSystem(
        start = 'XFF2-AFF2-XFF2-AFF',
        rules = dict(
            F = '', 
            Y = 'FFY',
            X = '+!X!FF-BQFI-!X!FF+',
            A = 'BQFI',
            B = 'AFF'
            ),
        turn_angle_deg = 45
    )
    
def settings():
    py5.size(w, h)

def setup():
    sketch_title('MPeano')

    production = grammar2.generate(mpeano, 6)
    py5.background(0, 0, 255)
    py5.stroke(255, 255, 0)
    py5.stroke_weight(3)
    render(production)    

def render(production):
    """
    Render evaluates the production string and calls draw_line
    """
    delta = radians(mpeano.turn_angle_deg)
    distance = 15
    turtle = {'x': w / 10, 'y': h / 10, 'angle': -delta}
    repeat = 1
    for val in production:
        if val == "F":
            turtle = draw_line(turtle, distance)
        elif val == "+":
            turtle['angle'] += delta * repeat
            repeat = 1
        elif val == "-":
            turtle['angle']-= delta * repeat
            repeat = 1
        elif val == "I":
          distance *= 1/sqrt(2)
        elif val == "Q":
            distance *= sqrt(2)
        elif val == "!":
            delta = -delta
        elif (val == '2'):
            repeat = 2
        else:
            pass

def draw_line(turtle, length):
    """
    Draw line utility uses processing 'line' function to draw lines
    """
    turtlecopy = turtle.copy()
    turtlecopy['x'] = turtle['x'] + length * cos(turtle['angle'])
    turtlecopy['y'] = turtle['y'] - length * sin(turtle['angle'])
    py5.line(turtle['x'], turtle['y'], turtlecopy['x'], turtlecopy['y'])
    return turtlecopy

def sketch_title(title):
    py5.get_surface().set_title(title)

py5.run_sketch()

```

Here is my grammar2 module:-

```python
def generate(lsys, total_iterations):
    lstring = lsys.start
    rules = lsys.rules
    
    for i in range(total_iterations):
        str_buf = []
        for symbol in lstring:          
            str_buf.append(rules.get(symbol, symbol))
        lstring = ''.join(str_buf)          
    return lstring 

```

 ![mpeano](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/323c68a45ea995a36b1b8562af225f163f9462ce.png)

---

<div class="post-metadata">

**Author:** ![monkstone](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/monkstone/32/64_2.png) [@monkstone](https://discourse.processing.org/u/monkstone)\
**Post date:** [September 16, 2021, 6:50am UTC](https://discourse.processing.org/t/lsystems-travelling-salesman-in-py5/32255/2 "2021-09-16T06:50:00Z")

</div>

I have since updated my py5 lsystem examples at [github](https://github.com/monkstone/py5-examples/tree/main/module_mode/lsystems), but I will be returning to my ruby-processing projects for a while especially with new versions JRuby and jdk17 on the horizon…

---

<div class="post-metadata">

**Author:** ![jafal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jafal/32/19112_2.png) [@jafal](https://discourse.processing.org/u/jafal)\
**Post date:** [September 16, 2021, 10:40pm UTC](https://discourse.processing.org/t/lsystems-travelling-salesman-in-py5/32255/3 "2021-09-16T22:40:49Z")

</div>

Nice working and creative 👍👍
