Zählen in for-Schleife
-
Hallo,
ich hab hier einen Code-Schnipsel, der anstandslos compiliert wird. Allerdings tut er nicht das, was er soll.
In der inneren for-Schleife werden Werte eines double-Arrays (Geradenparameter) verarbeitet.
Mehrere Geraden bilden zusammen ein Polygon. Die Zuordnung erfolgt über die Nr.
Die äußere for-Schleife gibt jeweils einen Punkt(x,y) an die innere weiter.Das ganze soll ein Punkt-in-Polygon-Test sein. Wenn eine Gerade geschnitten wird, wird flag = 1, sonst ist flag = 0.
Schließlich soll das ganze in einem Array (aus Strukturen) geordnet abgespeichert werden.
Die Struktur besteht aus dem Array Schicht(Polygon-Nr. und Anzahl der Schnitte) sowie aus X und Y des betrachteten Punktes.
Ziel ist es, die Anzahl der Schnitte für jeden Punkt(x,y) mit jedem Polygon zu zählen.Leider werden die Schnitte nicht so hochgezählt, wie ich es erwarte. Es werden
jeweils entweder 0 oder 1 Schnitte gezählt.Vielleicht kann mir jemand auf die Sprünge helfen...
Achso, ich bin C-Anfänger. Habt ein Nachsehen, wenn der Code etwas holprig wirken sollte.
int flag; double xa; double ya; double xe; double ye; double m; double n; double xSP; double x; int Nr; struct PiP { int Schicht[5][2]; double X; double Y; }; struct PiP Schivek[anzahlXLam]; // 0 setzen for (i=0; i<anzahlXLam; i++){ for (j=0; j<5; j++) { Schivek[i].Schicht[j][0] = 0; Schivek[i].Schicht[j][1] = 0; Schivek[i].X = 0; Schivek[i].Y = 0; } } for (i=0; i<anzahlXLam; i++){ x = KreisLamSP[i][0]; y = KreisLamSP[i][1]; for (j=0; j<anzahl; j++) { xa = GerPar[j][4]; ya = GerPar[j][5]; xe = GerPar[j][6]; ye = GerPar[j][7]; m = GerPar[j][8]; n = GerPar[j][9]; flag = 0; if ((xa<xe) && (ya>ye)) { xSP = (y - n) / m; if ((x<xSP) && (y<ya) && (y>ye)) { flag=1; } } else if ((xa<xe) && (ya<ye)) { xSP = (y - n) / m; if ((x<xSP) && (y>ya) && (y>ye)) { flag=1; } } else if ((xa==xe) && (ya>ye)) { xSP = xa; if ((x<xSP) && (y<ya) && (y>ye)) { flag=1; } } else if ((xa==xe) && (ya<ye)) { xSP = xa; if ((x<xSP) && (y>ya) && (y<ye)) { flag=1; } } else if ((xa<xe) && (ya==ye)) { xSP = xa; if ((x<xSP) && (y==ya) && (y==ye)) { flag=1; } } Nr = (int)GerPar[j][0]; Schivek[i].Schicht[Nr-1][0] = Nr; Schivek[i].Schicht[Nr-1][1] += flag; // hier hochzählen Schivek[i].X = x; Schivek[i].Y = y; } }
Gruß Beeker
-
was steht in GerPar[...][0..9] ?
GerPar[j][0] scheint nirgends einen wert zu bekommen.
-
Moin,
GerPar[][] wird in einem vorherigen Programmabschnitt mit den aus einem txt-file eingelesenen Geradenparanetern gefüllt. Das Array sieht dann so aus:
Pro Zeile: | Nr | G | P | C | xa | ya | xe | ye | m | n |
Nr...Polygon-Nr. (hierüber erfolgt die Zuordnung, welche Gerade zu welchem Polygon gehört)
G,P,C...Parameter, die die physikal. Eigenschaften eines Polygons beschreiben (werden erst später im Programm benötigt)
xa,ya,xe,ye...Anfangs- und Endpunkt-Koordinaten (mit Bubble-Sort geordnet, so dass xa immer <= xe)
m,n = Steigung, Ordinate des Schnittpunktes der Gerade mit der y-AchseGerPar[][] ist double, Nr muss aber int sein (wurde nur als double eingelesen), deswegen hab ich unten im Code nach int konvertiert.
Edit: Es sind natürlich Strecken, keine Geraden.
-
Ich blick da nicht durch. Ich würde das Problem in Teilprogramme zerlegen und nach jedem Schritt die Zwischenergebnisse ausgeben lassen.
-
Beeker, wenn du irgendwelche hochsprachen beherrschen solltest (sprachen wie z.b. python, scheme, ruby... jedenfalls mit memory management), dann prototypisiere dein programm erstmal. die implementationsdetails in C verwirren oft.
-
@keksekekse: Ja, du hast schon recht. Das werde ich auch noch machen. Das Programm ist insgesamt noch umfangreicher, so dass mir sowieso nichts anderes übrig bleiben wird. Das gesamte Programm, so wie es bis jetzt steht, ist erstmal nur eine Quick&Dirty-Lösung.
@c.rackwitz: Nein, andere Programmiersprachen sind mir völlig fremd. Ich beschäftige mich erst seit kurzer Zeit mit C. Ist quasi meine erste.
Deinen Link habe ich gelesen. Willst du mich auf pointer und funktionen aufmerksam machen?Ich weiß, mein Code ist nicht sehr elegant. Es ist aber das, was ich mit meinem jetzigen Kenntnisstand realisiert kriege.
Vielleicht erkläre ich mal das Vorgehen:
Was wird in der 2. verschachtelten for-Schleife gemacht:
Ein Punkt aus KreisLamSP[][x,y] wird an die innere Schleife weitergegeben. Man denke sich eine horizontale Gerade, die durch diesen Punkt verläuft. In der inneren Schleife wird jetzt die Absisse des Schnittpunktes dieser gedachten Geraden mit der Strecke aus GerPar[][] berechnet. Wenn der Schnittpunkt rechts des Ausgangspunktes liegt, dann wird flag auf 1 gesetzt. Am Ende der inneren Schleife wird dann der getestete Punkt aus KreisLamSP[][] und die Nr aus GerPar[][] in das Array aus Strukturen gespeichert, und zwar in die betreffende Struktur an die Stelle Nr-1. Außerdem wird das flag zur vorhandenen Anzahl der Schnittpunkte (die steht in Schicht[][1]) addiert. Zwar werden beim Durchlauf der Schleife einige Parameter in der Struktur überschrieben, jedoch sind es die gleichen, die vorher auch schon an dieser Stelle standen. Effektiv verändert sich also nur die Anzahl der Schnitte mit jedem Durchlauf.
Nachdem alle Punkte aus KreisLamSP[][x,y] und alle Strecken aus GerPar[][] durchlaufen wurden, habe ich schließlich ein Array aus Strukturen, in dem folgendes stehen sollte:Schicht[0,1,2,3,4][Nr, Anzahl der Schnitte] (Zum Testen erstmal 5 Polygone, das ganze wird später noch variabel)
X Absisse des Punktes aus KreisLamSP[][]
Y Ordinate des Punktes aus KreisLamSP[][]Das heisst, ich habe jetzt jedem Punkt aus KreisLamSP[][] die Nr. eines Polygons (das ganze 5mal, da 5 Polygone) zugeordnet. Außerdem sollte die Anzahl der Schnitte im Array Schicht[][] stehen.
Ausgabe etwa so:
Punkt 1: 6 Schnitte mit Polygon 1
Punkt 1: 7 Schnitte mit Polygon 2
...
Punkt 1: 4 Schnitte mit Polygon 5das ganze dann für alle Punkte aus KreisLamSP[][]
Alles klappt, nur die Anzahl der Schnitte wird nicht hochgezählt.
Wenn ich mir das Array aus Strukturen ausgeben lasse, wird die Anzahl mit 0 bzw. 1 angegeben. Ich kann mir das nicht erklären...
-
Beeker schrieb:
Willst du mich auf pointer und funktionen aufmerksam machen?
eher nein, nur auf die moeglichkeit, dein problem in sprachen auszudruecken, bei denen du dich nur aufs problem konzentrieren musst.
wenn du nur punkt-in-poly testen willst/musst, hier gibts etwas dazu:
http://www.cee.hw.ac.uk/~alison/ds98/node116.html
http://astronomy.swin.edu.au/~pbourke/geometry/insidepoly/
http://alienryderflex.com/polygon/ich kann mir aber gut vorstellen, dass du deinen eigenen code zum laufen bekommen willst.
ich blicke gerade nicht durch deinen code durch, also kann ich nichts konkretes dazu sagen.
du koenntest aber (wenn du keinen debugger haben solltest) mit printf() verschiedene variablen ausgeben lassen und verfolgen, ob diese die gewuenschten werte annehmen.
-
Danke für die Links. Der C-Code ist schonmal ne feine Sache für mich.
Allerdings hast du Recht: Ich möchte gerne meinen Code zum Laufen kriegen. Dabei ist der Punkt-in-Poly-Test gar nicht mal so wichtig. Es geht mir nur um die Addition des flags im unteren Teil meines Codes, denn diese wird scheinbar nur einmal ausgeführt.
Ich habe in meinem letzten Post versucht, die Schleife nochmal in Worte zu fassen.
Was genau verstehst du an meinem Code nicht? Ich könnte auch eine Zeichnung anfertigen, um es plausibel zu machen.
-
Beeker schrieb:
Was genau verstehst du an meinem Code nicht?
ich bin nur zu faul, mir das durchzulesen und einen sinn zu finden. normalerweise wuerde ich das ganze kompilieren, ausfuehren, mit nem debugger durchlaufen und dabei gucken, wie sich die variablen veraendern und ob sie das auch so machen sollen.
-
Alles klar, kann ich nachvollziehen.
Nun gut, ich werd mich erstmal weiter mit Sache beschäftigen. Hab da schon eine Idee...
Trotzdem danke für deine Antworten.
-
So, Fehler gefunden...
In der ersten else-if-Anweisung ist die Bedingung falsch.
Es muss heißen: y<ye
... dämlicher Tippfehler