ich habe eine Matrix die Werte zwischen 100 und 800 enthält. Dabei liegen geschlossene Kurven aus gleichen Werten vor. Durch den Befehl contour von Matlab kann ich mir diese Kurven (vgl. Höhenschichtlinien) anzeigen lassen.
Ich möchte nun wissen, ob vielleicht eine dieser geschlossenen Kurven in einer anderen geschlossenen Kurve enthalten ist.
Gibt es dafür einen einfachen Matlab-Befehl, oder muss ich dafür ein eigenes Skript schreiben.
Es geht dabei um das Innere einer geschlossenen Kurve C für beliebige Punkte. Will man zwei Kurven vergleichen, überprüft man jeden Punkt der anderen Kurve D und kann damit die Frage nach Inklusion beantworten.
Falls du das tatsächlich umsetzt, wäre es nicht schlecht, wenn du das Skript hier im Form an der entsprechenden Stelle publizieren könntest. Das dürfte für andere Anwender sehr interessant sein, denke ich.
vielen Dank für deine Hilfe, dass ist eigentlich genau das was ich brauche.
Leider hab ich die Implementierung in Matlab noch nicht hin bekommen, d.h. das Skript funktioniert nicht wie es soll.
Vielleicht kann mir wer sagen was nicht stimmt:
Hier die Matlab-Implementierung:
Code:
Polygon = Contour{v,4};
wn = 0;
for j=1:length(Polygon)-1 if Polygon(j,2) <= Point(2) if Polygon(j+1,2) > Point(2) var = isLeft(Polygon(j,:),Polygon(j+1,:),Point);
ifvar > 0
wn = wn+1;
end end else if Polygon(j+1,2) <= Point(2) var = isLeft(Polygon(j,:),Polygon(j+1,:),Point);
ifvar < 0
wn = wn-1;
end end end end
Und hier die Originalversion des Algorithmus in C++ von der Website:
Code:
// wn_PnPoly(): winding number test for a point in a polygon
// Input: P = a point,
// V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
// Return: wn = the winding number (=0 only if P is outside V[])
int
wn_PnPoly( Point P, Point* V, int n ) {
int wn = 0; // the winding number counter
// loop through all edges of the polygon
for(int i=0; i<n; i++){ // edge from V[i] to V[i+1] if(V[i].y <= P.y){ // start y <= P.y if(V[i+1].y > P.y) // an upward crossing
if(isLeft( V[i], V[i+1], P) > 0) // P left of edge
++wn; // have a valid up intersect } else{ // start y > P.y(no test needed) if(V[i+1].y <= P.y) // a downward crossing
if(isLeft( V[i], V[i+1], P) < 0) // P right of edge
--wn; // have a valid down intersect } } return wn;
}
// isLeft(): tests if a point is Left|On|Right of an infinite line.
// Input: three points P0, P1, and P2
// Return: >0for P2 left of the line through P0 and P1
// =0for P2 on the line
// <0for P2 right of the line
//
inline int
isLeft( Point P0, Point P1, Point P2 ) { return((P1.x - P0.x) * (P2.y - P0.y)
- (P2.x - P0.x) * (P1.y - P0.y));
}
%Abgeschlossenheit des Polygons setzen
polygon_x(end+1)=polygon_x(1);
polygon_y(end+1)=polygon_y(1);
%zu überprüfender Punkt
point=[0.5,0];
polygon=[polygon_x;polygon_y];
polygon=polygon';
wn = 0;
for j=1:length(polygon)-1 if polygon(j,2) <= point(2) if polygon(j+1,2) > point(2) var = isLeft(polygon(j,:),polygon(j+1,:),point);
ifvar > 0
wn = wn+1;
end end else if polygon(j+1,2) <= point(2) var = isLeft(polygon(j,:),polygon(j+1,:),point);
ifvar < 0
wn = wn-1;
end end end end
hold on
plot(polygon_x,polygon_y) plot(point(1),point(2),'o') hold off
if(wn==0) disp('Der Punkt liegt ausserhalb der geschlossenen Kurve');
else disp('Der Punkt liegt innerhalb der geschlossenen Kurve');
end
Noch zur Info: Ich habe deinen Code im Grunde nicht verändert. Ich habe lediglich ein korrektes Beispiel für ein Polygon (geschlossene Kurve) erzeugt. Du hattest das also völlig korrekt umgesetzt.
Das ganze nun auf eine vollständige andere Kurve zu übertragen dürfte nicht schwer sein. Man muss eigentlich nur ein Funktion daraus bauen und mit einer Schleife alle Punkte durchgehen.
besten Dank noch einmal für deine Hilfe. Mein Programm funktioniert jetzt auch, es lag auch nicht am Algorithmus sondern an einer for-Schleife in welcher der Algorithmus implementiert ist.
Vielen Dank und schöne Grüße,
Thomas
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.