Sierpinski-Kurve

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BeneCrack
User
Beiträge: 9
Registriert: Sonntag 20. Januar 2008, 13:04
Kontaktdaten:

Hallo Leute.
Ich muss bis nächste Woche ein Programm schreiben mit dem man eine Sierpinski Kurve zeichnen kann. Nur leider ist es so schwer dass ichs einfach nicht hin bekomme. Ich hab unter Wikipedia (http://de.wikipedia.org/wiki/Sierpi%C5%84ski-Kurve) nach geschaut wie das ganze funktionieren soll. Dort is auch schon ein Beispiel in Java geschrieben.
Also hoffentlich könnt ihr mir helfen.
Bis jetzt hab ich nur dass zusammengebracht:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*- 

import Image
import ImageDraw
import random
import sys


	
class SierpinskiKurve:
	
	global dist0 
	dist0 = 128
	global dist
	dist = 128
	bild = "Kurve.pdf"
	groesse = (800, 800)
	global image
	image = Image.new("1", groesse, color=255)
	  
	  
	level = 3
	
	
	
	def lineRel(deltaX, deltaY):
		zahler = 0
		if zahler == 0:
			xx = 2 * dist
			yy = dist	
			zahler = 1
		x = 2 * dist
		y = dist	
		draw = ImageDraw.Draw(image)
		draw.line ( (x, y) , x + deltaX, y + deltaY )
		xx += deltaX   
		yy += deltaY
		
	
	

	
	
	
	
	def sierpA (level):
		if (level > 0):
			sierpA(level-1)    
			lineRel(+dist,+dist)
			sierpB(level-1)   
			lineRel(+2*dist,0)
			sierpD(level-1)    
			lineRel(+dist,-dist)
			sierpA(level-1)
		


	def sierpB (level):
		if (level > 0):
			sierpB(level-1)    
			lineRel(-dist,+dist)
			sierpC(level-1)    
			lineRel(0,+2*dist)
			sierpA(level-1)    
			lineRel(+dist,+dist)
			sierpB(level-1)
		


	def sierpC (level):
		if (level > 0):
			sierpC(level-1)    
			lineRel(-dist,-dist)
			sierpD(level-1)    
			lineRel(-2*dist,0)
			sierpB(level-1)    
			lineRel(-dist,+dist)
			sierpC(level-1)
		


	def sierpD (level):
		if (level > 0):
			sierpD(level-1)    
			lineRel(+dist,-dist)
			sierpA(level-1)    
			lineRel(0,-2*dist)
			sierpC(level-1)    
			lineRel(-dist,-dist)
			sierpD(level-1)
	
	
	dist = dist0
	
	for i in range(0,level):
		dist /= 2
	
	sierpA(level) 
	lineRel(+dist,+dist)
	sierpB(level)     
	lineRel(-dist,+dist)
	sierpC(level)        
	lineRel(-dist,-dist)
	sierpD(level)        
	lineRel(+dist,-dist)
	image.save(bild) 
	print 'saved as: %s' % bild
	sg.show()
	

bild = SierpinskiKurve()
Danke

Edit (Leonidas): Nikolas hat recht - Thread verschoben.
BlackJack

Du solltest mit dem Python-Tutorial aus der Dokumentation anfangen und erst einmal Python lernen. Dieser Quelltext funktioniert ja nun *überhaupt nicht*. Das ist im Grunde nicht einmal Python sondern etwas das so ähnlich aussieht.

Ich habe auch so ein bisschen das Gefühl Du hast einfach etwas zusammen geschrieben und nicht nachgedacht. `lineRel()` enthält zum Beispiel solchen "WTF?"-Code.

Da `lineRel()` über Aufrufe hinweg die jeweils letzten Koordinaten verwenden muss, musst Du die Grundlagen bis einschliesslich Objektorientierung (OOP), also eigene Klassen, drauf haben, bevor Du Dich an diese Aufgabe wagst. Das OOP liesse sich auf das Zeichen beschränken, indem man die Zeichenfläche, in diesem Fall das `Image` und die `lineRel()`-Methode in einem Objekt unterbringt. Diese Klasse entspräche dann von der Funktion her der `SimpleGraphics` von der Wikipedia-Seite. Der Rest liesse sich dann mit einfachen Funktionen umsetzen.

Ein Bitmap-Bild würde man übrigens eher als PNG speichern. PDF macht da nicht soviel Sinn und ich weiss auch gar nicht, ob PIL das von Haus aus auf jeder Plattform kann.
BeneCrack
User
Beiträge: 9
Registriert: Sonntag 20. Januar 2008, 13:04
Kontaktdaten:

Ich hab eh schon vorher ein Programm mit zwei Klassen geschrieben, nur da waren noch mehr Fehlermeldungen drinn wie vorher. Ich hab wirklich keine Ahnung wie ich das bis nächste Wochhe DO programmiren soll. Python hab ich eh schon gelern nur mit dem PIL kenn ich mich nicht so ganz aus. Und PIL kann eh Bilder in PDF speichern, dass muss ich ja auch in meiner Aufgabe machen.
Kann mir keiner eine ungefähre Lösung posten wie ich das bewähltigen soll?

Ich bitte um Hilfe.
BlackJack

Eine ungefähre Lösung hast Du schon. Du musst jetzt nur noch verstehen was die tut und Python lernen. Deine Probleme haben wenig bis gar nichts mit PIL zu tun. Das sind ganz fundamentale Fehler die Python-Grundlagen betreffen.

PIL kann auch Bilder als PNG speichern. Das ist wirklich ein besseres Format als PDF für simple schwarz/weisse *Pixel*-Grafiken.

Dir hier eine Lösung zu präsentieren ist keine Hilfe, weil Du dadurch nicht lernst wie man es selber macht.

Fang mit einzelnen Komponenten an und teste diese. Zum Beispiel erst einmal eine Klasse für die Grafik und entwickle dann Stück für Stück entweder eine Klasse oder eine Funktion welche die Sierpinski-Kurve zeichnet. Dabei sollte jeder Zwischenschritt fehlerfrei ausführbar sein. Ein dermassen fehlerbehafteter Quelltext, wie Du ihn im ersten Beitrag gezeigt hast, in ein funktionsfähiges Programm um zu wandeln, bringt nur Frust.
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Der Witz von Serpinksi ist doch die Rekursitivät. Und du schreibst nur was für die drei untersten Stufen...

schau dir mal die turtle-sprache an. Da ist diese Figur in unter 20 Zeilen wunderbar lösbar.
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
BeneCrack
User
Beiträge: 9
Registriert: Sonntag 20. Januar 2008, 13:04
Kontaktdaten:

Hab wieder alles neue bearbeitet aber es kommen noch immer Fehlermeldungen und ich hab keine Ahneung wie ich es ausbessern soll oder woran es liegt könnt ihr mir bitte sagen was ich besser machen kann. BITTE
Hier ist der Source:

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import Image
import ImageDraw

class SimpleGraphics:
	groesse = (800, 800)
	im = Image.new("1", groesse, color=255)
    xx = 0 
	yy = 0   
	
    goToXY(x, y):
		xx = x  
		yy = y
		
	getImage():
		return im
	
    lineRel(deltaX, deltaY):
		draw = ImageDraw.Draw(im)
		draw.line((xx, yy), fill=128)
        x += deltaX;    y += deltaY;

class SierpinskiKurve:
	dist0 = 128;
    dist = 128;
	level = 3
	bild = "bild.bmp"
	
	def sierpA (level):
		if (level > 0):
			sierpA(level-1)    
			SimpleGraphics.lineRel(+dist,+dist)
			sierpB(level-1)   
			SimpleGraphics.lineRel(+2*dist,0)
			sierpD(level-1)    
			SimpleGraphics.lineRel(+dist,-dist)
			sierpA(level-1)
		


	def sierpB (level):
		if (level > 0):
			sierpB(level-1)    
			SimpleGraphics.lineRel(-dist,+dist)
			sierpC(level-1)    
			SimpleGraphics.lineRel(0,+2*dist)
			sierpA(level-1)    
			SimpleGraphics.lineRel(+dist,+dist)
			sierpB(level-1)
		


	def sierpC (level):
		if (level > 0):
			sierpC(level-1)    
			SimpleGraphics.lineRel(-dist,-dist)
			sierpD(level-1)    
			SimpleGraphics.lineRel(-2*dist,0)
			sierpB(level-1)    
			SimpleGraphics.lineRel(-dist,+dist)
			sierpC(level-1)
		


	def sierpD (level):
		if (level > 0):
			sierpD(level-1)    
			SimpleGraphics.lineRel(+dist,-dist)
			sierpA(level-1)    
			SimpleGraphics.lineRel(0,-2*dist)
			sierpC(level-1)    
			SimpleGraphics.lineRel(-dist,-dist)
			sierpD(level-1)
	
	
	dist = dist0
	
	for i in range(0,level):
		dist /= 2
	
	sierpA(level) 
	lineRel(+dist,+dist)
	sierpB(level)     
	lineRel(-dist,+dist)
	sierpC(level)        
	lineRel(-dist,-dist)
	sierpD(level)        
	lineRel(+dist,-dist)
	image = SimpleGraphics.getImage()
	image.save(bild) 
	print 'saved as: %s' % bild
	image.show()
	
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

In den Zeilen 14, 18 und 21 fehlen die ``def``s. Ließ dir ein Tutorial zu OOP in Python durch, das was du machst wirst du nicht durch zusammenhacken von *irgendwas* lösen können.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Vielleicht wäre der Thread auch besser bei den allgemeinen Fragen und nicht bei den ShowCases aufgehoben.
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
BlackJack

@BeneCrack: Du musst die Hilfe aber auch annehmen. Nochmal: Python bis einschliesslich OOP lernen, dann das Programm Stückchen für Stückchen implementieren und immer testen statt einen grossen Quelltext zu schreiben, der vor Fehlern nur so strotzt.

Bevor Du nicht halbwegs sicher mit Klassen und Objekten umgehen kannst, brauchst Du mit der Aufgabe gar nicht erst anfangen.
BlackJack

Das Programm von der Wikipediaseite in FreeBASIC umgesetzt: http://paste.pocoo.org/show/22789/

Die Funktionen habe ich durch "Steuerdaten" ersetzt. Würde ich bei einer Python-Lösung auch machen.
SonGuko
User
Beiträge: 11
Registriert: Montag 21. Januar 2008, 19:31

wennde einen einfachen code für die sirpinskikurve haben willst, kann ich dir nur die seite von meinem infolehrer empfehlen ^^
http://www.g-ymnasium.de/?option=com_co ... &Itemid=55
BeneCrack
User
Beiträge: 9
Registriert: Sonntag 20. Januar 2008, 13:04
Kontaktdaten:

OK, danke Leute, aber ich hab mich entschieden es selber zu machen und hab ma ein paar Tutorials angschaut. Ich hab es "besser" gemacht aber da kommt bei mir so eine Fehlermeldung in Zeile 21:
IndentationError: unindent does not match any outer indentation level

Code: Alles auswählen

class Sierpinski:
    def __init__(self, size):
        self.image = Image.new('1', size, color = 255)
        self.draw = ImageDraw.Draw(self.image)
   
    
    def save(self, filename):
        self.image.save(filename)
        print 'saved as: %s' % filename
        return True
   
    def show(self):
        self.image.show()
        return True


class SierKurve(Sierpinski):
	thisX = 0
	thisY = 0
	
    def __init__(self, size):
        Sierpinski.__init__(self, size)
   
    
	
   def goToXY(self, x, y):
		SierKurve.thisX = x  
		SierKurve.thisY = y
		
   
   def lineRel(self, deltaX, deltaY):
		c = canvas.canvas()
		c.stroke(path.line(SierKurve.thisX, SierKurve.thisY, deltaX, deltaY))
        SierKurve.thisX += deltaX  
		SierKurve.thisY += deltaY

class SierpinskiKurve(Sierpinski, SierKurve):
	dist = 128
	dist0 = 128
	def __init__(self, size):
        SierKurve.__init__(self, size)
	
	def generate(self, level):
		SierKurve.dist = SierKurve.dist0
		
		for i in range(0,level):
			SierKurve.dist /= 2
		
		self.goToXY(2*SierpinskiKurve.dist,SierpinskiKurve.dist);
		self.sierpA(level) 
		self.lineRel(+SierpinskiKurve.dist,+SierpinskiKurve.dist)
		self.sierpB(level)     
		self.lineRel(-SierpinskiKurve.dist,+SierpinskiKurve.dist)
		self.sierpC(level)        
		self.lineRel(-SierpinskiKurve.dist,-SierpinskiKurve.dist)
		self.sierpD(level)        
		self.lineRel(+SierpinskiKurve.dist,-SierpinskiKurve.dist)
	
	def sierpA (self, level):
		if (level > 0):
			self.sierpA(level-1)    
			self.lineRel(+SierpinskiKurve.dist,+SierpinskiKurve.dist)
			self.sierpB(level-1)   
			self.lineRel(+2*SierpinskiKurve.dist,0)
			self.sierpD(level-1)    
			self.lineRel(+SierpinskiKurve.dist,-SierpinskiKurve.dist)
			self.sierpA(level-1)
		


	def sierpB (self, level):
		if (level > 0):
			self.sierpB(level-1)    
			self.lineRel(-SierpinskiKurve.dist,+SierpinskiKurve.dist)
			self.sierpC(level-1)    
			self.lineRel(0,+2*SierpinskiKurve.dist)
			self.sierpA(level-1)    
			self.lineRel(+SierpinskiKurve.dist,+SierpinskiKurve.dist)
			self.sierpB(level-1)
		


	def sierpC (self, level):
		if (level > 0):
			self.sierpC(level-1)    
			self.lineRel(-SierpinskiKurve.dist,-SierpinskiKurve.dist)
			self.sierpD(level-1)    
			self.lineRel(-2*SierpinskiKurve.dist,0)
			self.sierpB(level-1)    
			self.lineRel(-SierpinskiKurve.dist,+SierpinskiKurve.dist)
			self.sierpC(level-1)
		


	def sierpD (self, level):
		if (level > 0):
			self.sierpD(level-1)    
			self.lineRel(+SierpinskiKurve.dist,-SierpinskiKurve.dist)
			self.sierpA(level-1)    
			self.lineRel(0,-2*SierpinskiKurve.dist)
			self.sierpC(level-1)    
			self.lineRel(-SierpinskiKurve.dist,-SierpinskiKurve.dist)
			self.sierpD(level-1)
	
Könnt Ihr mir bitte sagen was das für ein Fehler ist, weil meines wissents hab ich da nichts falsch.
BeneCrack
User
Beiträge: 9
Registriert: Sonntag 20. Januar 2008, 13:04
Kontaktdaten:

Sorry in Zeile 22.
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Da muss nicht unbedingt was falsch sein, könnte vlll auch am editor liegen. Lösch die zwei Zeilen kurz und schreib sei neu, oder schieb sie ganz nach links und rücke neu ein.

Warum hast du eigentlich immer noch das Sierpinkisky A bis D ? Da Ändern sich doch nur ein paar Faktoren, die du auch als argumente übergeben kannst.
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Oder, ganz allgemein: Du hast eine Fehlermeldung? Wie lautet sie denn? Wie geht Dein Skript an der Stelle?
Nikolas
User
Beiträge: 102
Registriert: Dienstag 25. Dezember 2007, 22:53
Wohnort: Freiburg im Breisgau

Hat er doch geschrieben: Es war ein IndentFehler, daher macht sein Skript gar nichts, wenn der Fehler kommt :)
Erwarte das Beste und sei auf das Schlimmste vorbereitet.
BeneCrack
User
Beiträge: 9
Registriert: Sonntag 20. Januar 2008, 13:04
Kontaktdaten:

Hallo

Diese SierpA - B Funktionen hab ich desswegen weil ich diese Aufgabe
rekursiv lösen muss. :lol:
BeneCrack
User
Beiträge: 9
Registriert: Sonntag 20. Januar 2008, 13:04
Kontaktdaten:

Ich hab jetzt die Zeile neu geschrieben (ganz links und dann eingerückt) und es kommt noch immer dieser Fehler.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

ah, erst habe ich übersehen, wo der Fehler liegt. Aber schau doch mal auf die Position der 'def's, die dahinter folgen. Na? Liegen die alle an derselben Stelle? Am besten nimmst Du einen Editor, der Dir bei der Einrückung hilft. Wie schon gesagt: Wenn Du Tabs und Leerzeichen gemischt hast, kannst Du solche Fehler auch provozieren. Gute Editoren zeigen auf Wunsch auch an, ob Tabs oder Leerzeichen vorliegen und machen auch Korrekturen.

Gruß,
Christian
BlackJack

@BeneCrack: Rekursiv lösen heisst nicht, dass man *vier* Funktionen braucht, das geht auch mit einer. Siehe das BASIC-Beispiel. Die Regeln kann man auch in eine Datenstruktur stecken. Dann lässt sich der gleiche Code dazu nutzen mit anderen Regeln auch andere Kurven zu zeichnen.

Die Klassenaufteilung ist übrigens unsinnig. Am Ende landet doch alles in einer Klasse, warum sind das also drei "verschiedene"? Der Inhalt von `Sierpinski` und `SierKurve` sollte eine Klasse sein. Und da die nichts mit Sierpinski im besonderen zu tun hat, wäre ein allgemeinerer Name angebracht. `Canvas` zum Beispiel. Die unbedingten ``return True`` am Ende von `save()` und `show()` sind überflüssig und sollten weg fallen.

Dann sind die letzten Koordinaten Klassenattribute, wo sie besser Instanzattribute sein sollten. Auf `dist` und `dist0` sollte man auch besser über `self` zugreifen. Und wenn das Klassenkonstanten sein sollten, wäre komplette Grossschreibung der Namen eine gute Idee, um das deutlicher zu machen.

Der Inhalt von `SierpinskiKurve` braucht nicht in einer Klasse zu stecken. Hier reichen ganz normale Funktionen.
Antworten