Registriert: So Okt 21, 2007 14:16 Beiträge: 123
Programmiersprache: Delphi
Hallo,
ich habe ein Dreieck und ein Polygon (2D) und möchte nun das Polygon vom Dreieck "wegschneiden", also die Dreiecke ermitteln, die das Dreieck minus das Polygon ergeben. Habe im Anhang eine kleine Skizze gemacht (violett: Ursprungsdreieck, grün: Polygon, schwarz: die gesuchten Dreiecke). Für Hilfe wäre ich sehr dankbar.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Das Thema haben wir mal in einem Thread über GUI gehabt.
Ich habe eine Lösungsansatz genutzt, wo ich leider gerade nicht den namen kenne :\ .
Man nimmt ein äusseren Punkt und sucht den kürzesten inneren Punkt dazu.
Die beiden Punkte bilden eine Kante(Edge), welche die Fläche in eine offenes Polygon aufteilt.
Nun kann man einen sehr einfachen Algo verwenden, der prüft, ob ein Punkt ein sogenanntes Ohr(es liegt kein Punkt zwischen den zu bildenen Triangle) und convex ist, dann kann man die aktuellen 3 Punkte verbinden. Dann sucht man den nächsten Punkt und füllt das Polygon somit mit Triangle auf.
Vieleicht kennt wer den Namen des Algos ^^ und hier ist noch die Umsetzung zu finden https://svn.linuxprofessionals.org/filedetails.php?repname=karmarama&path=%2Fprerelease%2Fwrapper%2FKar_OGLContext.pas .
Die Methode procedure TKar_OGLShape.Tesselieren; ist das wichtige, der rest gehört entweder zur gui oder sind Hilfsfunktionen für die Tesselierung.
Der Algo betrachtet allerdings nur offene Polygone, also musst du noch die Verticeliste entsprechend, dem oben genannten Schritt zum öffnen durchführen.
Das Problem was bei den ganzen Tesselieralgos gibt sind geschlossende Polygone, wie sie bei deinem gewollten Ergebnis entstehen und die oben genannten Variante(das Polygon zu öffnen) macht den algorythmus wesentlich einfacher und um ein vielfaches schneller.
Also ist im Prinzip der erste Schritt immer zu gucken, ob deine Schnittmenge ein offenes Polygon ergibt und wenn nicht muss es geöffnet werden.
Dann kannst du über ein Algo deiner Wahl das Polygon sehr einfach tesselieren.
Der Vorteil daran ist, dass man es nicht sieht, dass es ein offenes Polygon ist, man merkt es nur an dem Speicherverbrauch, da 2 Vertice mehr anfallen oder bei indizierten verticelisten 2 indices mehr anfallen.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: So Okt 21, 2007 14:16 Beiträge: 123
Programmiersprache: Delphi
Hallo,
erst einmal vielen Dank für die Antwort. Ich habe versucht, es nach deinem Ratschlag zu realisieren, es klappt jedoch nicht. FCalculatedVertice sind doch die Ausgangskoordinaten und FTriangleIndices die zu berechnenden Dreicke? Ich habe den folgenden Code geschrieben:
Code:
var
BaseTr:array[0...2]of TPoint;
CutPoints:arrayof TPoint;
[...]
BaseTr[0]:= Point(10,10);
BaseTr[1]:= Point(150,10);
BaseTr[2]:= Point(10,150);
SetLength(CutPoints,3);
CutPoints[0]:= Point(20,20);
CutPoints[1]:= Point(90,20);
CutPoints[2]:= Point(15,90);
[...]
hcp :=High(CutPoints);
MaxDist := MaxSingle;
for i :=0to hcp do
begin
x :=Sqrt(Sqr(BaseTr[0].x-CutPoints[i].x)+Sqr(BaseTr[0].y-Cutpoints[i].y));
if x < Maxdist then
begin
maxdist := x;
cp := i;
end;
end;
SetLength(points,4+hcp);
for i :=0to2do
points[i]:= BaseTr[i];
for i :=2to hcp+3do
begin
points[i]:= CutPoints[(i+cp)mod hcp];
end;
und in deinem Code FCalculatedVertice durch Points ersetzt (und die Datentypen entsprechend angepasst). Wenn jetzt das array l die Länge 5 hat, berechnet er 2 Dreiecke und das wars. Wenn l die Länge 6 hat, rechnet er sich zu Tode (findet 1 Dreieck und kein weiteres). Hat jemand eine Idee, was ich falsch mache? Für Hilfe wäre ich sehr dankbar.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Also die 3 Listen die du hast sind richtig, nun füllst du eine mit den verticedaten, eine mit den zu schneidenen polygon und eine bleibt erstmal leer.
Nun musst du für jedes Vertice, aus deinem Triangle, die Länge zu jedem Vertice des zu schneidenen Polygons nehmen.
Du hast einfach das erste Vertice genommen, was natürlich bei steigender komplexität von Orginal und zu schneidenem Polygon falsch wird(es könnte ein Vertice dazwischen liegen und damit würde man keine Kante bilden können).
Wenn du nun die kürzeste Verbindung ermittelt hast, dann kannst du in die Leere liste nun die Vertice vom Triangle hinzufügen.
Die Vertice sollten sortiert werden, erst nach Y und wenn doppelte Y werte auftreten dann nach X sortieren.
Registriert: So Okt 21, 2007 14:16 Beiträge: 123
Programmiersprache: Delphi
Hallo,
schonmal vielen Dank, es klappt habe den Ratschlag befolgt und vom Basis-Triangle auch den nächsten Punkt gesucht und die Punkte nach dem 2. Link korrekt sortiert. Das ganze hat noch ein paar Bugs (bleibt manchmal hängen oder es fehlen einige Triangles), aber ich denke das wird noch klappen. Nochmal vielen Dank, TAK2004!
Registriert: So Okt 21, 2007 14:16 Beiträge: 123
Programmiersprache: Delphi
Hallo,
meine Version war doch etwas instabil und hatte auch einige Macken (Triangles fehlten ab und zu, das Programm blieb öfters hängen), aber im Wiki war was sehr hilfreiches (hab in den Statistiken gestöbert und das ziemlich weit unten gefunden).
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Is gerade erst 1-2 Wochen alt. Vielleicht war dein Thread sogar die Inspiration dazu. Falls du dich mit Triangulation genauer beschäftigst, kannst du uns gern auf dem Laufenden halten und selber Wiki Einträge verfassen.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.