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
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.
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.
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
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
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