2015-08-02 16 views
9

Für meine aktuelle Universitätsarbeit sollen wir ein Sierpinksi-Dreieck erstellen und rekursiv neue Dreiecke hineinzeichnen.Sierpinski's Triangle Pygame Recursive

Der ursprüngliche Code, den wir bekamen, war dies:

import sys, pygame 

# a function that will draw a right-angled triangle of a given size anchored at a given location 
def draw_triangle(screen, x, y, size): 
     pygame.draw.polygon(screen,white,[[x,y], [x+size,y], [x,y-size]]) 

############################################################################################# 
# Define a function that will draw Sierpinski's Triangle at a given size anchored at a given location 
# You need to update this function 
# currently only one triangle is drawn 

def sierpinski(screen, x, y, size): 
     draw_triangle(screen, x, y, size) 

############################################################################################# 

# Initialize the game engine 
pygame.init() 

# Define the colors we will use in RGB format 
black = [ 0, 0, 0] 
white = [255,255,255] 
blue = [ 0, 0,255] 
green = [ 0,255, 0] 
red = [255, 0, 0] 

# Set the height and width of the screen 
size=[512, 512] 
screen=pygame.display.set_mode(size) 

# Loop until the user clicks the close button. 
done=False 
clock = pygame.time.Clock() 


while done==False: 

    # This limits the while loop to a max of 10 times per second. 
    # Leave this out and we will use all CPU we can. 
    clock.tick(10) 

    for event in pygame.event.get(): # User did something 
     if event.type == pygame.QUIT: # If user clicked close 
      done=True # Flag that we are done so we exit this loop 

    # Clear the screen and set the screen background 
    screen.fill(black) 

    # Draw Sierpinski's triangle at a given size anchored at a given location 

    sierpinski(screen,0, 512, 512) 

    # Go ahead and update the screen with what we've drawn. 
    # This MUST happen after all the other drawing commands. 
    pygame.display.flip() 

# Tidy up 
pygame.quit() 

Ok ich weiß, dass dies nur ein einziges Dreieck entsteht. Hier ist, was ich tat, um es „Art“ funktioniert:

ich ein neues Dreieck Funktion erstellt eine den Kopf Dreieck zu zeichnen:

def draw_upside_down_triangle(screen, x, y, size, color): 
     pygame.draw.polygon(screen, color, [[x+size, y+size], [x+size, y], [x, y]]) 

Dann aktualisiert ich die alte Dreiecksfunktion eine Farbe variabel zu akzeptieren :

def draw_triangle(screen, x, y, size, color): 
     pygame.draw.polygon(screen, color, [[x, y], [x+size, y], [x, y-size]]) 

Danach habe ich die Hauptfunktion aktualisiert, die rekursiv Dreiecke zeichnen wird:

def sierpinski(screen, x, y, size): 
    if size < 10: 
     return False 
    else: 
     draw_triangle(screen, x, y, size, white) 
     draw_upside_down_triangle(screen, x, y/2, size/2, black) 
     sierpinski(screen, x+size/2, y+size/2, size/2) 
     sierpinski(screen, x, y-size/2, size/2) 
     sierpinski(screen, x, y, size/2) 
     sierpinski(screen, x, y+size/2, size/2) 

begann ich die Funktion aus

  1. Durch den Ausgang Argument Hinzufügen (wenn das Dreieck ist zu klein return false bekommen)
  2. Wenn es nicht zu klein ist, dann weiß
  3. das erste Dreieck zeichnen Danach ein Unentschieden auf den Kopf gestellt Dreieck die Hälfte der Größe an der gleichen Stelle x aber die Hälfte der Y-Position in schwarz (dies schafft die 3-Dreieck-Illusion)
  4. Nach all dem habe ich 4 rekursive Anrufe, basierend auf Experimenten, die ich weiß, dass die Reihenfolge Diese Aufrufe sind wichtig, da sich die Ausgabe beim Ändern radikal ändert.

Im Moment ist der Stromausgang ist wie folgt:

Sierpinski's Triangle Pygame Recursive

ich nicht für jedermann bin zu fragen meinem Code einfach ein besseres Verständnis oder einen Punkt in der richtigen Richtung zu beenden oder zu korrigieren. Habe ein paar Stunden mit diesem gekämpft.

Danke!

+0

Erinnert mich an eines meiner frühen pygame-Skripte, wo ich ein Sierpinski-Dreieck mit der Technik [chaos game] (https://en.wikipedia.org/wiki/Chaos_game) gezeichnet habe. – elParaguayo

Antwort

3

einen Blick auf den folgenden Link Nehmen Sie die Sierpinski Dreieck implementiert ...

http://interactivepython.org/runestone/static/pythonds/Recursion/graphical.html#sierpinski-triangle

Viele gute Diskussion um das Problem und 40 einige Zeilen Code, sie umzusetzen.

Auch wegen der Funktionsweise des Turtle-Moduls können Sie jedes Dreieck einzeln betrachten. Dies ist sehr hilfreich, wenn Sie den Code überprüfen, da Sie die Rekursionsebenen und deren Auftreten visualisieren können. Ich weiß nicht, wie schwer dies in pygame zu implementieren wäre, aber wenn Sie die Erstellung des Dreiecks verlangsamen können, ist es viel einfacher, die Logik zu verstehen.

Sie sagen, Sie brauchen die 4 rekursiven Aufrufe basierend auf dem Experiment, aber können Sie die Logik dahinter erklären? Intuitiv erscheint das falsch, da Sie nur drei neue Dreiecke plus ein teilweise gedecktes Elternteil benötigen, um vier kleineren gleichseitigen Dreiecken zu entsprechen. (Sehen Sie, wie das in der Verbindung geschieht?)

Können Sie erklären, warum Sie eine umgekehrte Dreiecksmethode verwenden? Das scheint so etwas wie ein fehleranfälliges Problem zu sein? Sie sollten in der Lage sein, die umgekehrten Dreiecke mit negativem Abstand von Ihrer normalen Dreiecksfunktion zu zeichnen. In der Verknüpfung sehen Sie, dass der Autor ein grünes Dreieck in die gleiche Richtung wie alles andere zeichnet, aber später mit mehr Dreiecken bedeckt, bis der grüne in die entgegengesetzte Richtung zeigt.

Alles in allem sieht es so aus, als wären Sie in der Nähe. Sie müssen nur das letzte Stück Rekursionslogik richtig machen.

P.S.

Eine kleinere Nebenstil Kritik - nur weil dies in Python geschrieben und Lesbarkeit zählt. Sie können While True und dann break verwenden, um die zusätzliche Variable done zu vermeiden.

+0

danke für die Hilfe! Es war ein Schritt in die richtige Richtung, aber es ist noch nicht ganz fertig. Ich habe mein gesamtes Skript wieder auf das ursprüngliche Skript zurückgesetzt, dann habe ich den Farbparameter der Dreiecksfunktion hinzugefügt. Ich änderte die Hauptfunktion, indem ich den gleichen Break Case wie zuvor verwendete und eine neue Logik hinzufügte, um zuerst ein Basisdreieck und dann 3 Subdreiecke zu zeichnen, danach rekursiv die Funktion 3 Mal aufzurufen, um Dreiecke in diesen 3 Subdreiecken zu zeichnen. Ich habe den Code hier in [Pastebin] eingefügt (http://pastebin.com/f6qyahwj) –

+0

Das Problem ist, dass das erste Dreieck in der oberen linken Ecke jetzt nicht gedruckt wird. PS die Haupt-Looping-Funktion ist wie vom Professor zur Verfügung gestellt, so werde ich nichts ändern, die sie nicht markieren, aber danke für die Köpfe :) –

+0

Endlich geschafft, es zu tun, danke für die Hilfe! –