Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hilbert Curve Analysis

Tags:

python

I'm just starting to learn Python and I don't understand the ability of calling the same function inside itself?

Here is an example:

import turtle
from turtle import left, right, forward

size = 10

def hilbert(level, angle):
    if level == 0:
        return

    turtle.color("Blue")
    turtle.speed("Fastest")

    right(angle)
    hilbert(level - 1, -angle)
    forward(size)
    left(angle)
    hilbert(level - 1, angle)
    forward(size)
    hilbert(level - 1, angle)
    left(angle)
    forward(size)
    hilbert(level - 1, -angle)
    right(angle)

How exactly does this work?

Thanks.

like image 701
ElectroNerd Avatar asked Aug 28 '11 00:08

ElectroNerd


People also ask

What is concept of Hilbert curve?

The Hilbert curve is a space filling curve that visits every point in a square grid with a size of 2×2, 4×4, 8×8, 16×16, or any other power of 2. It was first described by David Hilbert in 1892. Applications of the Hilbert curve are in image processing: especially image compression and dithering.

What are Hilbert curves used for?

The Hilbert Curve is commonly used among rendering images or videos. Common programs such as Blender and Cinema 4D use the Hilbert Curve to trace the objects, and render the scene.

How do you calculate Hilbert curve?

vector, fh = [ φh ψh ] , as shown in Equations 4–7. partition etc., leading to the conclusion that each square in the n-th partition is a Hilbert curve scaled by the factor of 2−n traversed in a time 4−n.

What is topological dimension of Hilbert curve?

Although a topological dimension of the Hilbert curve (as well as of any other curve) is one, a topological dimension of the filled square is two.


4 Answers

I couldn't accept that the beauty of recursion was not understanding it, nor could I accept the fact that I might not be able to understand it myself! So after consulting a friend, I finally became aware of how the stack works. Here is my equivalent code for the Space Filling Hilbert Curve if level = 2 and angle = 90°:

import turtle
from turtle import left, right, forward

size = 10
angle = 90

turtle.hideturtle()
turtle.color("Blue")
turtle.speed("Fastest")

''' Assume we have two levels. '''

right(angle)

# 1st hilbert call
right(-angle)
forward(size)
left(-angle)
forward(size)
left(-angle)
forward(size)
right(-angle)

# Continue from first call of hilbert
forward(size)
left(angle)

# 2nd hilbert call
right(angle)
forward(size)
left(angle)
forward(size)
left(angle)
forward(size)
right(angle)

# Continue from second call of hilbert
forward(size)

# 3rd hilbert call
right(angle)
forward(size)
left(angle)
forward(size)
left(angle)
forward(size)
right(angle)

# Continue from third call of hilbert
left(angle)
forward(size)

# 4th call of hilbert
right(-angle)
forward(size)
left(-angle)
forward(size)
left(-angle)
forward(size)
right(-angle)

# Continue from fourth call of hilbert
right(angle)

Eureka!

like image 105
ElectroNerd Avatar answered Sep 28 '22 03:09

ElectroNerd


When level equals 0, hilbert(level,angle) just returns, that is, does nothing.

Now consider what happens when level equals 1: Calling hilbert(1,angle) executes these statements:

turtle.color("Blue")
turtle.speed("Fastest")
right(angle)
forward(size)
left(angle)
forward(size)
left(angle)
forward(size)
right(angle)

It looks to me that this probably draws three sides of a square.

The hilbert(level-1,...) statements have been removed since level-1 equals 0 and we already determined that hilbert(0,...) does nothing.

Now, consider what happens when you call hilbert(1,-angle). Next, think about what happens when level equals 2. I hope this gives you an idea of how to proceed.

PS. Lovely thing about Python -- you can run programs interactively to visualize what calling hilbert(1,angle) does, then hilbert(2,angle) does, etc...

like image 40
unutbu Avatar answered Sep 28 '22 03:09

unutbu


This is a powerful programming technique called recursion, where a problem is solved by breaking it down into similar but smaller problems, until you reach a point where the problem is small enough to solve easily.

like image 40
Tom Zych Avatar answered Sep 28 '22 02:09

Tom Zych


As @Tom Zych and others mentioned, this is a problem called recursion that can be hard to wrap your mind around at first (sometimes requires thinking about problems in a totally different way than usual).

The most classic and easily understood (but not necessarily useful or powerful) example of recursion is the factorial generator. Given a positive integer n, the factorial of n is equal to the product of all the positive integers less than or equal to n. We write the factorial of n as n!:

n! = n * (n-1) * (n-2) * ... * 3 * 2 * 1

Now with recursion we want to see, "what is the pattern here that repeats and gets simpler as I try to solve the larger problem?" Let's try 5! for instance:

5! = 5 * 4 * 3 * 2 * 1

What is the first thing we do when solving this equation? We take 5 and multiply it by something. This is perfect, because if we had a factorial function fact(n), we would probably take n as its parameter:

def fact(n):
    return n * #something

All that remains is to figure out what that #something is. But we just wrote it above:

5! = 5 * (4 * 3 * 2 * 1)

But how is out new #something just a smaller problem that is essentially identical to our original problem? Watch, this is the magic of recursion:

5! = 5 * 4 * 3 * 2 * 1
   = 5 * 4!
4! = 4 * 3 * 2 * 1
   = 4 * 3!
3! = 3 * 2 * 1
   = 3 * 2!
2! = 2 * 1
   = 2 * 1!
1! = ???

As you can see, for most any given n,

n! = n * (n-1)!

We're almost there, now that we've discovered our pattern, we need to worry about the exception case, the simplest case, (when n = 1, there's nothing else to multiply by). In recursion, we call this the base case, and fortunately we know exactly what to do in this base case: 1! = 1. So in summarizing our logic, we can write our recursive factorial function:

def fact(n):
    # Take care of the base case first
    if n == 1:
        return 1
    # Then break down the larger case into its recursive sub-problems
    else:
        return n * fact(n-1)

Your Hilburtle program is a tad bit more intricate, but if you know some of what Hilbert curve analysis is about, and you're beginning to understand recursive program logic, you should be able to figure out how it works. Good luck!

like image 43
machine yearning Avatar answered Sep 28 '22 03:09

machine yearning