Flächeninhalt eines Vielecks

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

MacroMan

Betreff: Flächeninhalt eines Vielecks

BeitragSo, Mai 22, 2011 16:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,
ich überlege gerade, wie man den Flächeninhalt eines Vielecks berechnen kann. Alle Seiten sind dabei parallel bzw. orthogonal (90°) zueinander. Ich habe alle Eckpunkte des Vielecks angegeben. Kennt jemand dazu einen Algorithmus (muss nicht unbedingt Blitz sein) oder kann mir erklären, wie ich das machen soll.
Meine Vorgehensweise war bisher (überraschenderweise) so: Ich teile das Vieleck in kleinere Recktecke auf und addiere deren Flächeninhalte. Mein Problem besteht hauptsächlich darin, zu unterscheiden, ob ein Teilrechteck aus 4 Eckpunkten des Vielecks tatsächlich innerhalb des Vielecks liegt oder ob es (teilweise) aus dem Vieleck herausragt.

Vielen Dank schon mal im Voraus!

ZaP

BeitragSo, Mai 22, 2011 17:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Wikipedia meint, die Trapezformel von Gauß ist dafür geeignet, sofern das Teil eben ist.
Starfare: Worklog, Website (download)
 

MacroMan

BeitragSo, Mai 22, 2011 18:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, aber der Wikipedia-Artikel ist ein wenig kompliziert. Daraus werde ich leider kein bisschen schlauer.

darth

BeitragSo, Mai 22, 2011 18:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

der Link zeigt direkt zur Formel die du brauchst. Das grosse, gezackte E da ist ein Sigma und bezeichnet eine Summe. Sowas kann man meist wunderbar mit Schleifen umsetzen (For-Next). Wobei du einfach über die Punkte zählst.

Du hast also eine Liste von Punkten (Typeeinträge) in deinem Polygon
BlitzBasic: [AUSKLAPPEN]
Local ptList.TPoint[10]; 10 Punkte, 0 - 9


Die Punkte haben jeweils eine X und Y Koordinate (2D). Jetzt musst du eigentlich nur die angegebene Summe umsetzen, und dann durch zwei dividieren.
BlitzBasic: [AUSKLAPPEN]
sum# = 0
j = 9
For i = 0 To 9
sum = sum + (ptList[j]\x + ptList[i]\x) * (ptList[i]\y - ptList[j]\y)
j = i
Next
sum = Abs( sum ) /2


Unter der Formel steht, dass das (n+1) als 1 betrachtet werden muss (also Modulo n). Das mache ich, indem ich zuerst j auf n setze (hier 9), und dann nachher "hinter dem i herschleppe", d.h j wird immer das vorhergehende i sein und wenn ich dann durch alle i gehe, habe ich immer den "hinteren" Nachbarn für j. (D.h hier ist i := (i+1) und j := i in der Wiki Formel.)

MfG,
Darth

Edit:
*Seufz*, jaja, natürlich hast du recht mpdingsda. Der Absolutwert kommt erst zum Schluss. Habs kurz reineditiert. Meh!
Diese Signatur ist leer.
  • Zuletzt bearbeitet von darth am So, Mai 22, 2011 23:32, insgesamt einmal bearbeitet

Midimaster

BeitragSo, Mai 22, 2011 19:21
Antworten mit Zitat
Benutzer-Profile anzeigen
So wie das bei Dir klingt, können in dem Polygon aber Innenwinkel von 270° auftauchen, oder?

wie hier:
BlitzBasic: [AUSKLAPPEN]
 _________
|____ |
| |
|____|



Da geht doch der Gaus gar nicht...

Ich würde den Polygon von BB in rot ausmalen lassen und dann bei einer geplanten Berechnung eines Teil-Rechtecks in dem entstandenen Bild "nachsehen" ob der "Mittelpunkt" dieses Rechteckes auf ein rotes Pixel zeigt.

mpmxyz

BeitragSo, Mai 22, 2011 19:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Doch, das sollte gehen, wenn man den Code korrigiert: Abs muss zum Schluss kommen und nicht für jeden Teilbetrag benutzt werden, da diese nicht ohne Grund negativ werden können.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer
 

MacroMan

BeitragSo, Mai 22, 2011 20:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Das, was Midimaster sagt, ist korrekt: Ich möchte auch Innenwinkel von 270° berücksichtigen. Wenn dies nicht so wäre, würde das ganze Vieleck ja nur ein Rechteck sein...

@Midimaster: Die Idee mit dem Ausmalen hatte ich auch schon, aber das ist mir zu langsam. Ich suche eigentlich nach einer "rechnerischen", mathematischen Lösung...

[EDIT] @mpmxyz: Das versteh' ich nicht. Warum sollten die Teilbeträge nicht negativ werden können?
[EDIT2] Den letzten Edit nicht beachten. Ich habe mpmxyzs Antwort falsch verstanden.
  • Zuletzt bearbeitet von MacroMan am Mo, Mai 23, 2011 16:23, insgesamt einmal bearbeitet

Midimaster

BeitragSo, Mai 22, 2011 22:39
Antworten mit Zitat
Benutzer-Profile anzeigen
aus wievielen Ecken besteht denn ein durchschnittlicher deiner geplanten Poylgone? Da ja nur ein Mittelpunkt pro Teilflächen auf Farbe kontrolliert werden muss, würde ich mal schätzen, dass bei Poygone unter 100 Ecken die Abfrage noch nicht mal messabr sein wird, unter 10.000 wird es immer noch im erträglichen Bereich bleiben....

SpionAtom

BeitragSo, Mai 22, 2011 23:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem, das du hast, scheint sehr mit dem Rechteckaufteile-Problem zusammenzuhängen. Wenn du deine Fläche in Rechtecke aufteilen kannst - die Rechtecke also kennst - so hast du im Nu auch den Flächeninhalt.

http://stackoverflow.com/quest...-algorithm
Hier wird so ein Rechteck-Aufteile-Algorithmus beschrieben.
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080

Tobchen

BeitragMo, Mai 23, 2011 0:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe keine Ahnung, in wie weit dir Spions Algo helfen soll, aber ich meine auch, dass es mit Scanline und Teilrechtecken geht.
Ist denn ausgeschlossen, dass die Figur so aussieht? Problemfigur (Das Problem ist hier, dass das Polygon hier sich irgendwann in "zwei" Teile aufteilt (siehe die beiden "Beine").) Wenn du nie solche Figuren haben wirst, kann ich dir eventuell einen Algorithmus beschreiben, der das Ding in Teilrechtecke aufteilen kann.

Edit: Spion erinnerte mich im Chat gerade an Divide and Conquer. Das müsste man dann tatsächlich darauf anwenden können, wenn sich die Scanline "entzwei teilt" Das sollte aber auch nur funktionieren, wenn man neben den Koordinaten der Eckpunkte auch noch Informationen darüber hat, welche die Nachbarpunkte eines Punkts. Wird noch komplizierter, wenn die "Beine" nach oben statt nach unten schauen.

Hier mein Versuch zur Beschreibung des Algos für die unproblematische Figur:
Man sortiert alle Eckpunkte der Y-Koordinate nach (von oben nach unten).
Dann nimmt man die ersten beiden Punkte in dieser Liste und nimmt sie als die oberen Punkte für das erste Teilrechteck. Dieses Teilrechteck geht so lange nach unten bis zur Y-Koordinate des dritten Punkts.
Dann guckt man, ob die X-Koordinate des dritten Punkts rechts oder links vom Teilrechteck liegt.
Liegt sie links, beginnt man ein neues Teilrechteck von der Y-Koordinate des dritten Punkts und der X-Koordinate des dritten Punkts bis zur rechten X-Koordinate des vorigen Teilrechtecks.
Liegt sie rechts, beginnt man ein neues Teilrechteck von der Y-Koordinate des dritten Punkts und der rechten X-Koordinate des vorigen Teilrechtecks bis zur X-Koordinate des dritten Punkts.
Das neue Teilrechteck geht, was die Höhe angeht, bis zur Y-Koordinate des vierten Punkts.
Und so weiter.
Bitte beachte, dass der nächste Punkt auch mit dem übernächsten Punkt auf der gleichen Höhe liegen könnte. Das heißt, man sollte sich die nächsten beiden Punkte ansehen. Liegen sie auf gleicher Höhe, musst du das neue Teilrechteck vom X des dritten bis zum X des vierten Punkt gehen lassen.
Das letzte Teilrechteck endet auf der Höhe der letzten beiden Punkte in der Liste.

mpmxyz

BeitragMo, Mai 23, 2011 7:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Da schlug wohl die doppelte Verneinung fehl:
Die Teilbeträge sollten auch negativ werden können, da es ansonsten Fehler gibt.
Durch das falsch positionierte Abs funktionierte der Code nicht richtig. (Der Code wurde korrigiert.)
Der Sinn der Vorzeichen lässt sich anhand des hier gezeigten Bildes nachvollziehen:
http://de.wikipedia.org/wiki/G...l#Beispiel
(Da hier die Punkte im Uhrzeigersinn durchlaufen werden, ist das Ergebnis negativ.)
Das Trapez wird hierbei mit Hilfe von vier Teilflächen beschrieben, die alle von der X-Achse ausgehen.
Dabei werden die Teilfächen A2 und A3 auf die Gesamtfläche hinaufaddiert und die Flächen A1 und A4 abgezogen. (durch die Drehrichtung alles mit negativem Vorzeichen)
Ohne Beachtung der Vorzeichen würde der Teil zwischen der Fläche und der X-Achse doppelt gewichtet zur Gesamtfläche hinzugezogen werden.
mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Midimaster

BeitragMo, Mai 23, 2011 8:12
Antworten mit Zitat
Benutzer-Profile anzeigen
ich bin immer noch nicht überzeugt, ob das für sein Problem die richtige Formel ist. In dem Link heißt es ausdrücklich:

Zitat:
...also beispielsweise die Fläche eines einfachen Polygons...


dies bedeutet, dass kein Winkel im Polygon über 180° sein darf, oder?

@mpmxyz
Bist Du sicher, das die Formel auch diese Fläche korrekt berechnen würde:

BlitzBasic: [AUSKLAPPEN]
 _________
|____ |
| |
____| |
| |
|_____ |
| |
|____|

darth

BeitragMo, Mai 23, 2011 13:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich habs mal kurz ausprobiert (weil vor mir ja noch keiner unfaul genug war Razz) anhand von Midimasters Beispiel.

BlitzBasic: [AUSKLAPPEN]
Type TPoint
Field x#
Field y#
End Type

Function newPoint.TPoint(x#, y#)
Local p.TPoint = New TPoint

p\x = x
p\y = y

Return p
End Function

Local ptList.TPoint[10]

ptList[0] = newPoint(0, 0)
ptList[1] = newPoint(20, 0)
ptList[2] = newPoint(20, 50)
ptList[3] = newPoint(10, 50)
ptList[4] = newPoint(10, 40)
ptList[5] = newPoint(0, 40)
ptList[6] = newPoint(0, 30)
ptList[7] = newPoint(10, 30)
ptList[8] = newPoint(10, 20)
ptList[9] = newPoint(0, 20)

Graphics 800, 600, 0, 2
SetBuffer BackBuffer()

Local timer = CreateTimer(60)
While Not KeyHit(1)

sum# = 0
j = 9
For i = 0 To 9
sum = sum + (ptList[j]\x + ptList[i]\x) * (ptList[i]\y - ptList[j]\y)
j = i
Next
sum = Abs( sum ) /2

Text 10, 60, sum

j = 9
For i = 0 To 9
Line ptList[i]\x, ptList[i]\y, ptList[j]\x, ptList[j]\y
j = i
Next

Flip 0
WaitTimer(timer)
Cls
Wend
End


Das Ergebnis das der Code rausspuckt ist 800.

Hier die Überprüfung:
Die Figur ist zusammengesetzt aus 4 Rechtecken (horizontal),
1) 0/0 - 20/20 => 20 * 20 = 400
2) 10/20 - 20/30 => 10 * 10 = 100
3) 0/30 - 20/40 => 20 * 10 = 200
4) 10/40 - 20/50 => 10 * 10 = 100
Summe darüber, 400 + 100 + 200 + 100 = 800

Stimmt also.

Ich verwendete für die Massenberechnung (für das Inertial) in meiner Physikengine so ziemlich die gleiche Formel, und da habe ich bisher keine schwerwiegenden Fehler erhalten. Natürlich ist es schwer, die dort zu sehen, weil sowieso keine negativen Massen auftreten (durch das Abs), es ist dort eher Augenmass "oh, ja die Figur verhält sich schwerer als die andere".

Von daher.. Der Code funktioniert für diese Art von Figuren. Ich bin mir nicht ganz sicher ob er allgemein gilt, d.h auch für selbstüberschneidende Polygone, aber für konkave funktioniert er.

MfG,
Darth
Diese Signatur ist leer.
 

MacroMan

BeitragMo, Mai 23, 2011 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Erst mal Danke für die vielen Beiträge!

Midimaster hat Folgendes geschrieben:
Da ja nur ein Mittelpunkt pro Teilflächen auf Farbe kontrolliert werden muss, würde ich mal schätzen, dass bei Poygone unter 100 Ecken die Abfrage noch nicht mal messabr sein wird, unter 10.000 wird es immer noch im erträglichen Bereich bleiben....

@Midimaster: Das Überprüfen ist ja nicht das Problem. Nur das zeichnen und das Löschen danach wird lange dauern...

Tobchen hat Folgendes geschrieben:
Ist denn ausgeschlossen, dass die Figur so aussieht? Problemfigur

Leider nicht... Aber ich kenne die Reihenfolge des Eckpunkte im Vieleck (in der man das Vieleck zeichnen würde).

@Midimaster: Hier steht, dass ein einfaches Polygon ein Poligon ist, dessen Kanten sich nicht schneiden... (Seiten 4+5)

[EDIT] Nach mehrfachem Testen hat sich nun herausgestellt, dass darth's Lösung stimmt. Danke nochmals an alle!

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group