Forum: PC-Programmierung Start- und Endwerte von Teilstücke einer Kurve entsprechend der Reihenfolge des Verlaufs sortieren


von Guido C. (guidoanalog)



Lesenswert?

Hallo!

Hintergrund
Es gibt für Eagle (www.cadsoft.de) ein sogenanntes ULP (User Language 
Program), das es ermöglicht Durchkontaktierungen entlang eines 
vordefinierten Kurvenverlaufs setzen zu lassen. Die Bildschirmkopie im 
Anhang ("Drill_Array_Creator_1.21.png") verdeutlicht dies recht gut.

Das ULP mit der Bezeichnung "create_drill_line_array1.21.zip" kann hier 
http://www.cadsoft.de/downloads/ulps heruntergeladen werden.

Damit das ULP ordnungsgemäß funktioniert muss der Kurvenverlauf 
fortlaufend gezeichnet worden sein, da das ULP die Teilstücke der Kurve 
so abarbeitet, wie sie im Speicher abgelegt sind. Wird der Kurvenverlauf 
nicht wie auf der linken Seite in "create_drill_line_array1.21-Test.png" 
von 1 nach 2 und von 2 nach 3 gezeichnet sondern von 1 nach 2 und 
anschließend von 3 nach 4 ergibt sich ein Versatz. Ich möchte daher das 
ULP so anpassen, dass die Teilstücke der Kurve vor dem Setzen der VIAs 
entsprechend sortiert werden.

Meine Frage an Euch
Ich habe mehrere Arrays, die sowohl die Anfangs- als auch Endpunkte der 
Teilstücke der Kurve definieren. Diese Werte sind sowohl für 
Geradenstücke als auch für Kreisbögen definiert.

1
wire_x1[i]; // x-Startwert
2
wire_y1[i]; // y-Startwert
3
wire_x2[i]; // x-Endwert
4
wire_y2[i]; // y-Endwert

Irgendwie will mir derzeit kein (einfacher) Ansatz einfallen, wie ich 
diese Arrays so sortieren kann, dass die Teilstücke der Kurve gemäß 
ihrer geometrischen Reihenfolge in dem Array stehen. Das Problem ist, 
dass ein Teilstück auch verkehrt herum gezeichnet worden sein kann, d.h. 
das Start- und Endwert vertauscht sind. Habt ihr einen Lösungsansatz 
oder gar ein Beispiel für mich (idealerweise in C)? Gerne kann der 
Ansatz auch davon ausgehen, dass die Kurve nicht wie in 
"Drill_Array_Creator_1.21.png" gezeigt geschlossen ist.

Mit freundlichen Grüßen
Guido

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Kommt drauf an was über die Kurve bekannt ist.

Eine offensichtliche Lösung für den Fall dass die Kurve Rand oder Teil 
des Randes eines (im mathematischen Sinne) sternförmigen Gebiets ist.

1) Wähle einen Punkt M, so dass die Verbinungslinien M--Pi zu den 
Punkten Pi sich nicht überschneiden.  Weil die Kurve Rand eines 
sternförmigen Gebiets ist, existiert solch ein M.

2) Stelle die Pi in Polarkoordinaten bzgl. M dar und sortiere sie nach 
dem Winkel; die sortierten Punkte seien mit Si durchnumeriert.

3) Suche Paare S[i], S[i+1] mit S[i] ~ S[i+1], d.h. immer 2 Punkte, die 
sowohl in Radial- als auch in Polarkomponente (mod 2*pi) übereinstimmen 
bzw. so dicht liegen, dass man davon ausgehen kann, dass sie den selben 
Punkt darstellen sollen..

4) Du bekommst deine Segmente dann als S[1]--S[2], S[2]--S[4], 
S[4]--S[6]..., S[n-2]--S[n] und im Falle einer geschlossesen Kurve noch 
S[n]--S[1], d.h. dann n/2 Segmente.


Für 2) kannst du z.B. ein beliebig orientiertes kartesisches 
Koordinatensystem mit Ursprung in M verwenden und die Argumente mit 
atan2 berechnen falls es diese Funktion gibt.  Falls der Luxus komplexer 
Zahlen existiert kann man die Pi einfach als komplexe Zahl auffassen und 
arg(Pi) berechnen lassen falls es arg() gibt.


Für nicht-sternförmige Gebiete fällt mir auf Anhieb nur ein holpriger, 
rekursiver Ansatz ein, bei bedarf kann ich den weiter ausführen.

: Bearbeitet durch User
von Besucher (Gast)


Lesenswert?

Wenn ich die Beschreibung richtig verstanden habe muss die Kurve 
zusammenhängend sein, bzw. die zusammengehörigen Anfangs-/Endpunkte von 
zwei Teilstücken müssen exakt identische Koordinaten haben.

Dann sollte es schon ausreichen wenn dein Programm nur die Punkte 
vergleicht und zuordnet. Beim Start wählst du einen beliebigen 
Anfangs-/Endpunkt einer Kurve aus. Dann:
1. Gewählten Punkt mit allen anderen Anfangs-/Endpunkten vergleichen
2. Übereinstimmung: Gefundene Kurve schließt an die aktuelle Kurve an
3. Nächster Punkt ist das andere Ende der gefunden Kurve
4. Weiter bei 1.

Das machst du so lange bis alle Kurven sortiert sind. Wenn Punkte übrig 
bleiben ist die Kurve nicht geschlossen. Die ermittelte Reihenfolge 
legst du in einem Array ab und übergibst das (anstatt der 
Zeichen-Reihenfolge im Speicher) an die Funktion.

von Guido C. (guidoanalog)


Angehängte Dateien:

Lesenswert?

Hallo,

leider komme ich erste heute wieder dazu mich diesem Problem zu widmen. 
Um die Sache nicht unnötig kompliziert zu machen wollte ich nur 
"einfache" Kurven zulassen. Unter "einfache" Kurven verstehe ich Kurven, 
die aus einem Kurvenzug bestehen und keine Verzweigung besitzen. Ähnlich 
wie die Kurve in dem im Anhang gezeigten Bild. Die Zahlen in dem Bild 
geben an in welcher Reihenfolge die Linien (Wires) der Kurve gezeichnet 
wurden.

@Johann L. (gjlayde)
Ich denke ich habe Deinen Ansatz so weit verstanden. Ich fürchte jedoch, 
dass dieser Ansatz nicht so einfach umzusetzen ist. Es könnte auch 
Probleme mit spiralförmigen Kurven geben (Stichwort Printspule).

@Besucher (Gast)
Besucher schrieb:
> Wenn ich die Beschreibung richtig verstanden habe muss die Kurve
> zusammenhängend sein, bzw. die zusammengehörigen Anfangs-/Endpunkte von
> zwei Teilstücken müssen exakt identische Koordinaten haben.
Genau so ist es. Ich denke ich werde den von Dir beschriebenen Ansatz 
verfolgen.

Vielen Dank für Eure Unterstützung.

Mit freundlichen Grüßen
Guido

von Georg (Gast)


Lesenswert?

Guido C. schrieb:
>> zwei Teilstücken müssen exakt identische Koordinaten haben.
> Genau so ist es.

Exakt ist nicht unbedingt eine gute Idee, dann findet das Programm 
keinen Anschluss wegen Rundungsfehlern oder wegen nicht exakter 
Schnittpunktberechnungen. Ich würde eine kleine Differenz zulassen, und 
die parametrierbar machen. Erfahrungen mit CNC-Fräsprogrammen zeigen, 
dass das nötig ist, z.B. ist bei abgerundeten Ecken die 
Kreisbogenberechnung manchmal merklich daneben, so dass die Endpunkte 
der Geraden nicht genau mit denen des Kreisbogens übereinstimmen.

Noch ein anderer Punkt: für ein Fräsprogramm z.B. ist wichtig, in 
welcher Richtung die Kurve durchlaufen wird. Will man ein Loch fräsen, 
so muss man den Fräserradius nach innen korrigieren, d.h. wenn man den 
Umriss im Uhrzeigersinn abfährt, nach rechts (in Fräsrichtung). Bei 
einer Aussenkontur umgekehrt.

Georg

von Guido C. (guidoanalog)


Lesenswert?

Hallo,

Georg schrieb:
> Exakt ist nicht unbedingt eine gute Idee, dann findet das Programm
> keinen Anschluss wegen Rundungsfehlern oder wegen nicht exakter
> Schnittpunktberechnungen. Ich würde eine kleine Differenz zulassen, und
> die parametrierbar machen. Erfahrungen mit CNC-Fräsprogrammen zeigen,
> dass das nötig ist, z.B. ist bei abgerundeten Ecken die
> Kreisbogenberechnung manchmal merklich daneben, so dass die Endpunkte
> der Geraden nicht genau mit denen des Kreisbogens übereinstimmen.

vielen Dank für den Hinweis. Ich habe diesbezüglich bei EAGLE weniger 
bedenken. Wenn eine Kurve vollständig "geroutet" ist, schließt ein 
Kurvensegment immer an das nächste an. Dies liegt daran, weil EAGLE 
Kurvensegmente immer über die Start- und Endpunkte definiert. Unabhängig 
davon, ob es sich um Geradenstücke oder Kreisbogen handelt. Schließen 
die Kurvensegmente nicht unmittelbar aneinander an hat man geschlampt 
und wird durch mein ULP bestraft ;-)

Georg schrieb:
> Noch ein anderer Punkt: für ein Fräsprogramm z.B. ist wichtig, in
> welcher Richtung die Kurve durchlaufen wird. Will man ein Loch fräsen,
> so muss man den Fräserradius nach innen korrigieren, d.h. wenn man den
> Umriss im Uhrzeigersinn abfährt, nach rechts (in Fräsrichtung). Bei
> einer Aussenkontur umgekehrt.

Das stimmt. Auch beim Setzen der Durchkontaktierungen wird es eine Rolle 
spielen wo mit der ersten Durchkontaktierung begonnen wird und in 
welcher Richtung die Kurve durchlaufen wird.

Mit freundlichen Grüßen
Guido

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.