2015-08-02 21 views
9

Quindi per il mio attuale articolo universitario intendiamo creare un triangolo Sierpinksi e ricorsivamente disegnare nuovi triangoli all'interno.Triangolo di Sierpinski Pygame Ricorsivo

Il codice originale che abbiamo ottenuto è stato questo:

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 So che questo crea solo un singolo triangolo. Ecco quello che ho fatto per farlo funzionare "sorta di":

ho creato una nuova funzione triangolo per disegnare un triangolo capovolto:

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

Poi ho aggiornato la vecchia funzione triangolo di accettare una variabile di colore :

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

Dopo che ho aggiornato la funzione principale che ricorsivamente disegnare triangoli:

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) 

Ho iniziato la funzione off

  1. Aggiungendo l'argomento di uscita (quando il triangolo ottiene è troppo piccolo ritorno false)
  2. Se non è troppo piccola quindi disegnare il primo triangolo in bianco
  3. Dopo di che disegna un triangolo rovesciato metà delle dimensioni nella stessa posizione x ma metà della posizione in nero (questo crea l'illusione triangolare 3)
  4. Dopo tutto ciò ho 4 chiamate ricorsive, in base alla sperimentazione so che l'ordine di queste chiamate sono importanti in quanto l'output cambia radicalmente quando viene modificato.

Al momento l'uscita in corrente è il seguente:

Sierpinski's Triangle Pygame Recursive

Non sto chiedendo a chiunque di finire o correggere il mio codice semplicemente una migliore comprensione o un punto nella giusta direzione. Ho combattuto con questo per alcune ore.

Grazie!

+0

Mi ricorda uno dei miei primi script di pygame in cui ho disegnato un triangolo di Sierpinski usando la tecnica [gioco caos] (https://en.wikipedia.org/wiki/Chaos_game). – elParaguayo

risposta

3

Date un'occhiata al seguente link che implementa il triangolo di Sierpinski ...

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

Un sacco di buona discussione intorno al problema e 40 alcune righe di codice per attuarla.

Anche a causa del modo in cui il modulo tartaruga funziona, è possibile osservare ciascun triangolo ottenere il disegno uno per uno. Ciò è estremamente utile quando si esamina il codice perché è possibile visualizzare i livelli di ricorsione e quando si verificano. Non so quanto sarebbe difficile implementarlo in pygame, ma se riesci a rallentare la creazione del triangolo, ciò rende la comprensione della logica molto più semplice.

Hai detto che hai bisogno delle 4 chiamate ricorsive basate sull'esperimento ma puoi spiegarci la logica dietro? Intuitivamente, questo sembra sbagliato perché hai bisogno solo di tre nuovi triangoli più un genitore parzialmente coperto uguale a quattro triangoli equilateri più piccoli. (Vedi come questo è fatto nel link?)

Puoi spiegare perché stai utilizzando un metodo a triangolo capovolto? Questo sembra un po 'come un lavoro incline al bug in giro? Dovresti essere in grado di disegnare i triangoli capovolti usando lo spazio negativo dalla tua normale funzione triangolare. Nel link vedrai che l'autore disegna un triangolo verde rivolto nella stessa direzione di tutto il resto, ma in seguito lo copre con più triangoli finché quello verde è rivolto nella direzione opposta.

Tutto sommato sembra che tu sia vicino. Hai solo bisogno di ottenere l'ultimo pezzo di logica di ricorsione giusta.

P.S.

Una piccola critica di stile minore - solo perché è scritta in python e conteggi di leggibilità. È possibile utilizzare While True e quindi break per evitare la variabile extra done.

+0

grazie per l'aiuto! È stato un passo nella giusta direzione, ma non è ancora finito. Ho ripristinato il mio intero script con lo script originale fornito, quindi ho aggiunto il parametro del colore alla funzione triangolo. Ho modificato la funzione principale utilizzando lo stesso break case di prima e ho aggiunto qualche nuova logica per disegnare prima un triangolo di base e poi 3 triangoli secondari dopo che ricorsivamente chiamata la funzione 3 volte per disegnare triangoli in quei 3 triangoli secondari. Ho incollato il codice qui in [pastebin] (http://pastebin.com/f6qyahwj) –

+0

Il problema è che il primo triangolo nell'angolo in alto a sinistra non viene stampato ora. PS la funzione di looping principale è quella fornita dal professore, quindi non cambierò nulla su cui non stanno marcando, ma grazie per l'heads up :) –

+0

Finalmente riuscito a farlo grazie per tutto l'aiuto! –