Punkt in Polygon bestimmen

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.
feldmaus
User
Beiträge: 287
Registriert: Donnerstag 12. Oktober 2006, 16:48

Hallo Alle,

ich war mir jetzt nicht ganz sicher, ob ich einen neuen Thread zu diesem Thema aufmachen soll, da es ja schon ein paar gibt. Allerdings habe ich nicht alles verstanden und hätte gerne auch noch Eure Meinung zu meiner Kreation. :-)

Wie die Überschrift sagt will ich bestimmen ob ein Punkt innerhalb eines Polygons liegt, dazu nutze ich 2 Verfahren, die auf der Strahl-Methode aufsetzen. Eine Methode ist schnell und siebt die meisten Fälle raus und die zweite Methode siebt das über gebliebene nochmal raus.

Hier mein Code.
http://pastebin.com/m467e3e67

Ich habe in meinen Code eine Methode zum Testen implementiert, haltet Ihr meinen Stil für ok oder habt ihr daran eine Kritik zu äußern ?
Was haltet Ihr von meinem Dokumentationsstil ?

Hier ein Link wo die Methoden beschrieben sind, aber ich habe sie bis jetzt nicht ganz verstanden habe.
http://rw7.de/ralf/inffaq/polygon.html

Die Langsame Methode leuchtet mir noch nicht ganz ein. Vielleicht kann mir das Jemand auf eine andere Weise vielleicht nochmal erklären, speziell die Ignore-Variante. Der Author erzählt was von einem Fehler. Ist der dort angegebene Code nur korrekt ?

Grüße Markus
Zuletzt geändert von feldmaus am Freitag 10. Juli 2009, 10:00, insgesamt 7-mal geändert.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Was den Stil angeht:

Statt der unschönen if/else Kaskaden kannst du folgende etwas übersichtlichere Schreibweisen verwenden.

Code: Alles auswählen

def __testquick(self, point=point, polygon=polygon):
    if np.amin(polygon[0]) <= point[0] <= np.amax(polygon[0]) \
    and np.amin(polygon[1]) <= point[1] <= np.amax(polygon[1]):
        return True
    return False

# Oder gleich, wenn es in eine Zeile passt:

def __runTest(self, point, polygon):
    return self.__testquick(point, polygon) and self.__testslow(point, polygon)
Außerdem können die beiden Test-Methoden ruhig public sein, sie sind ja auch einzeln recht nützlich.

Und ich will hoffen, das du diesen Testmodus-Quatsch raus wirfst und anständige Unit-Tests schreibst ;)
Bottle: Micro Web Framework + Development Blog
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

`__irgendwas` ist nicht gut, weil schau mal was da rauskommt als Name:

Code: Alles auswählen

In [1]: class Foo(object):
   ...:     __a = 1

In [2]: dir(Foo())
Out[2]: 
['_Foo__a',
...
]
`__runTest` könntest du übrigens auch so schreiben:

Code: Alles auswählen

__runTest(self, point, polygon):
     return self.__testquick(point, polygon) and self.__testslow(point, polygon)
Gruß
feldmaus
User
Beiträge: 287
Registriert: Donnerstag 12. Oktober 2006, 16:48

Dauerbaustelle hat geschrieben:`__irgendwas` ist nicht gut, weil schau mal was da rauskommt als Name:

Code: Alles auswählen

In [1]: class Foo(object):
   ...:     __a = 1

In [2]: dir(Foo())
Out[2]: 
['_Foo__a',
...
]
Ich wollte die Methoden nach aussen verstecken. Das das nicht 100% möglich ist wie bei C++ weiss ich bereits. Aber zumindest ist es ein kleiner Schutz, oder meinst Du was anderes ?
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Code: Alles auswählen

In [1]: class Foo(object):
   ...:     __a = 1
   ...:     b = 2
   ...:     
   ...:     

In [2]: dir(Foo())
Out[2]: ['_Foo__a',
...,
 'b']
Na?
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Ich hatte mich gefragt wozu überhaupt eine Klasse Pointtest. Trägt irgendwie nichts bei zur Lösung. Was soll den eine Instanz der Klasse darstellen?
feldmaus
User
Beiträge: 287
Registriert: Donnerstag 12. Oktober 2006, 16:48

hendrikS hat geschrieben:Ich hatte mich gefragt wozu überhaupt eine Klasse Pointtest. Trägt irgendwie nichts bei zur Lösung. Was soll den eine Instanz der Klasse darstellen?
Du meinst, warum ich nicht alles in die __init__ Methode schreibe ? Weil sonst die __init__ Methode, die ja einen wesentlich Teil der Steuerung darstellt, das ganze zu unübersichtlich macht. Ich nutze gerne Methoden wo ich unübersichtlichen Balast auslagern kann.

Der Grundgedanke ist ja zwischen einem Testmodus und Praxismodus zu unterteilen. Allerdings kann der Praxismodus wieder unterteilt werden in eine schnelle und eine langsame Methode.

Grüße Markus
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Ansich sollte man dafür eine Funktion schreiben. So komplex ist der Algo doch nicht.

Vorstellbar wäre aber eine Klasse Polygon, die beispielsweise die Koordinaten der Eckpunkte enthält und vielleicht ein Attribut für konvex oder konkav. Dazu eine Methode isPointInPolygon(point).

Aus OOP Sicht der logischere Ansatz.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

hendrikS hat geschrieben:Vorstellbar wäre aber eine Klasse Polygon, die beispielsweise die Koordinaten der Eckpunkte enthält und vielleicht ein Attribut für konvex oder konkav. Dazu eine Methode isPointInPolygon(point).
Da würde man doch eher ``__contains__`` implementieren, so dass man ``point in Polygon()`` nutzen kann.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

@Leonidas: Das ist natürlich noch eleganter. Keine Frage.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

feldmann_markus hat geschrieben:Ich wollte die Methoden nach aussen verstecken.
Warum?
feldmaus
User
Beiträge: 287
Registriert: Donnerstag 12. Oktober 2006, 16:48

Dauerbaustelle hat geschrieben:
feldmann_markus hat geschrieben:Ich wollte die Methoden nach aussen verstecken.
Warum?
Damit anderer Programmierer die an meinem Projekt eventuell mitmachen nicht auf krumme Gedanken kommen. Das ist der Grundgedanke von privaten Attributen. Ansonsten wären wir wieder bei der Sicherheitsstufe Win95. :-)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dafür würde man wenn dann `_` nehmen. Außerdem ist sicherheit nicht gleich Sicherheit. Bei privaten Attributen geht es um API-Sicherheit, bei Sicherheit wie du das mit Win95 meinst geht es um Speicherschutz, wo Programme sich gegenseitig überschrieben konnten - also um Datensicherheit.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Leonidas hat geschrieben:Dafür würde man wenn dann `_` nehmen.
Aber dann ist das Attribut ja nicht mehr nach außen geschützt. Es wird ja extra umbenannt, dass es über den normalen Namen (außen) nicht benutzbar ist...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Und wenn es umbenannt ist, dann ist es wie geschützt? Es ist genauso zugreifbar wie wenn ein _ davor steht, nur ist es unangenehmer zu tippen und macht den Quellcode letztendlich nur hässlicher.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

In meinem Eclipse-Outline werden sie richtig schön als private Methoden angezeigt. ;) Das ist ja auch nur eine persönliche Ansichtssache...
Ich bleib da bei, oder gibt es was offizielles, was dagegen spricht?
feldmaus
User
Beiträge: 287
Registriert: Donnerstag 12. Oktober 2006, 16:48

Leonidas hat geschrieben:Und wenn es umbenannt ist, dann ist es wie geschützt? Es ist genauso zugreifbar wie wenn ein _ davor steht, nur ist es unangenehmer zu tippen und macht den Quellcode letztendlich nur hässlicher.
Gut das sehe ich schon ein. Allerdings wenn ich als Python Programmierer in einem Gruppen Projekt ein Python Modul benutzen soll, dass von anderen erstellt wurde, dann werde ich unter Umständen mal schauen, was das Ding so kann um meine Aufgabe zu erfüllen, allerdings ist es vielleicht gar nicht erwünscht das ich einige Methoden benutzen soll. Methoden die privat sind, sagen sogar mir als Python Anfänger, vorsicht diese Methode oder Eigenschaft darfst Du nicht direkt benutzen. Anders ist es, wenn dies eine Public Methode ist. Ich weiss als Programmierer nicht eindeutig, ob ich sie benutzen darf oder nicht. Da ich allerdings alles privat gemacht habe, sollte jedem klar sein, das ich nicht will, dass er diese Methoden der Klasse benutzt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Die Nutzer des Moduls sollte die Dokumentation lesen und wenn dort steht dass die Methode nicht benutzt werden sollte (oder gar nicht in der Dokumentation erwähnt wird, so wie Django das macht, als Beispiel für ein umfangreiches Framework) dann sollten sie auch wissen dass das eben keine gute Idee ist sie trotzdem zu nuten, da sie unter Umständen damit Probleme haben könnten.

Und Dokumentation muss man sowieso lesen, egal ob die Sprache nun ``private``-Keywords hat oder nicht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

ice2k3 hat geschrieben:In meinem Eclipse-Outline werden sie richtig schön als private Methoden angezeigt. ;) Das ist ja auch nur eine persönliche Ansichtssache...
Ich bleib da bei, oder gibt es was offizielles, was dagegen spricht?
PEP8 bezeichnet Namen mit einem fuehrenden `_` eindeutig als ``private`` und empfiehlt ``__`` nur, um Namenskonflikte zu vermeiden.

Um das ganze nochmal hervorzuheben: ``__`` loest NUR ein Name Mangling aus, dh der Name ist danach immernoch ueber ``_classname__name`` zugaenglich.
feldmaus
User
Beiträge: 287
Registriert: Donnerstag 12. Oktober 2006, 16:48

Leonidas hat geschrieben:Und Dokumentation muss man sowieso lesen, egal ob die Sprache nun ``private``-Keywords hat oder nicht.
Also würdest Du public oder schwach privat empfehlen ?
Antworten