0

I'm trying to plot a Moore curve (https://en.wikipedia.org/wiki/Moore_curve) in python. I've gotten as far as plotting a Hillbert curve, as there seems to be more resources on Hillbert vs Moore, but it's not clear to me how to edit the subsequent iterations of the curve to make it plot the Moore curve correctly.

This is the python code for the Hillbert curve:

def d2xy(n,d):
    t=d
    x=y=0
    s=1
    while s<n:
        rx=1&(t/2)
        ry=1&(t^rx)
        s,x,y,rx,ry=rot(s,x,y,rx,ry)
        x+=s*rx
        y+=s*ry
        t/=4
        s*=2
    return x,y

def rot(n,x,y,rx,ry):
    if ry==0:
        if rx==1:
            x=n-1-x
            y=n-1-y
        x,y=y,x

    return n,x,y,rx,ry

How can I change this to plot the Moore curve?

cdlane
  • 40,441
  • 5
  • 32
  • 81
aj_black
  • 31
  • 6
  • Please repeat [on topic](https://stackoverflow.com/help/on-topic) and [how to ask]( https://stackoverflow.com/help/how-to-ask) from the [intro tour](https://stackoverflow.com/tour). “Show me how to implement this feature” is not a Stack Overflow issue. You have to make an honest attempt, and *then* ask a *specific* question about your algorithm or technique. – Prune Aug 06 '20 at 21:12

1 Answers1

0

The Wikipedia page that you cite spells out how to do it using turtle graphics and an L-system. Just following those instructions, I came up with:

from turtle import Screen, Turtle

AXIOM = 'LFL+F+LFL'

RULES = {
    'L': '-RF+LFL+FR-',
    'R': '+LF-RFR-FL+',
}

DISTANCE = 300
CYCLES = 4

def draw(string, distance):
    for character in string:
        if character == 'F':
            turtle.forward(distance)
        elif character == '+':
            turtle.right(90)
        elif character == '-':
            turtle.left(90)
        else:
            pass  # ignore other characters

def produce(string):
    production = ''

    for character in string:
        if character in RULES:
            production += RULES[character]
        else:
            production += character  # just copy other characters

    return production

screen = Screen()
screen.tracer(False)

turtle = Turtle()
turtle.hideturtle()
turtle.setheading(90)

string = AXIOM

for _ in range(1, CYCLES):
    string = produce(string)

distance = DISTANCE / CYCLES ** 2  # crude estimate, fix this

draw(string, distance)

screen.tracer(True)
screen.exitonclick()

enter image description here

And the fun part is, having implemented our L-system, by just changing the data, not the code, we can also make the Hilbert curve:

from turtle import Screen, Turtle

AXIOM = 'A'

RULES = {
    'A': '-BF+AFA+FB-',
    'B': '+AF-BFB-FA+',
}

DISTANCE = 300
CYCLES = 6

# ...

enter image description here

Of course, the calculation of the distance variable does need a bit of work...

cdlane
  • 40,441
  • 5
  • 32
  • 81