arctan von ganzzahlige Brüchen < Diskrete Mathematik < Hochschule < Mathe < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 01:46 Fr 28.05.2021 | Autor: | Erhy |
Hallo!
Habe Brüche, wobei Zähler und Nenner ganzzahlig sind.
Sie repräsentieren Ausrichtungen in der Ebene.
Einem beliebigen derartigen Bruch
soll einem Listenelement aus solchen Brüchen zugeordnet werden,
bei dem die absolute Winkeldifferenz entsprechend Arkustangens am kleinsten ist.
Suche dazu eine effiziente Methode im Zuge eines Python Programms?
Geringe Ungenauigkeiten kann ich in Kauf nehmen.
Die Hürden bei dieser Aufgabe sind:
Der Nenner kann 0 sein.
Der Arkustangens ist unstetig und springt von [mm] 2\pi [/mm] auf 0
Danke für Euren Rat
Erhy
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 03:05 Fr 28.05.2021 | Autor: | Erhy |
Beispiel der Liste der Brüche:
4 / 4
3 / 4
2 / 4
1 / 4
0 / 4
-1 / 4
-2 / 4
-3 / 4
-4 / 4
-4 / 3
-4 / 2
-4 / 1
-4 / 0
-4 / -1
-4 / -2
-4 / -3
und dieser Bruch soll z.B. einem Element der obigen Liste zugeordnet werden:
23 / -15
|
|
|
|
|
Folgender Vorschlag:
Fasse alle Brüche als Vektoren auf. Der interessierende Vektor heiße [mm] \vec{a}.
[/mm]
Bilde die Skalarprodukte mit [mm] \vec{a}. [/mm] Dann ist [mm] \vec{a}*\vec{b}= |\vec{a}|*|\vec{b}|*cos(\alpha), [/mm] also
[mm] cos(\alpha)=\bruch{\vec{a}*\vec{b}}{|\vec{a}|*|\vec{b}|}
[/mm]
Dabei ist [mm] \alpha [/mm] die gesuchte Winkeldifferenz.
Dein Beispiel mit 23/-15 und 3/4:
[mm] |\vektor{23 \\ -15}| [/mm] = [mm] \wurzel{23^2+(-15)^2}=\wurzel{754}
[/mm]
[mm] |\vektor{3 \\ 4}| [/mm] = [mm] \wurzel{3^2+4^2}=\wurzel{25}=5
[/mm]
[mm] \vektor{23 \\ -15}*\vektor{3 \\4 }= [/mm] 23*3-15*4=9
[mm] cos(\alpha)=\bruch{9}{\wurzel{754}*5} [/mm]
[mm] \alpha \approx [/mm] 86,24 °.
Es gibt keine Probleme wie beim arctan, bei negativen cos-Werten kommt ein Winkel >90° heraus. Du erhältst immer den Winkel zwischen den Füßen der beiden Vektoren, wenn du diese aneinander legst.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 17:50 Fr 28.05.2021 | Autor: | Erhy |
Danke für Deinen Rat!
Es stimmt, dass mir die Matrizenrechnung fremd ist.
Habe das Beispiel nachgerechnet und komme auf das gleiche Ergebnis.
Das einzige Detail betreffend Matrizenrechnung, das ich angewandt habe,
ist die Numpy Funktion matmul .
Erhy
|
|
|
|
|
Falls du es noch gebrauchen kannst: Statt mit Matrizen zu rechen, hier die Vereinfachung:
Die Brüche sollen a/b und A/B heißen. Dann ist
[mm] cos(\alpha)=\bruch{aA+bB}{\wurzel{a^2+b^2}*\wurzel{A^2+B^2}}
[/mm]
Mehr an Funktionen ist nicht nötig.
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 15:09 Fr 28.05.2021 | Autor: | chrisno |
Mein Vorschlag:
Berechne eine Liste mit Zahlen, die jeweils die Grenze zwischen der Entscheidung, zu welchem Bruch der Wert zugeordet werden soll, darstellen.
Für die Einordnung musst Du dann nur noch schauen, zwischen welchen beiden Werten aus der Liste der einzuordnende Bruch liegt.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 23:35 Fr 28.05.2021 | Autor: | Erhy |
Hallo!
Denke, es ist mir jetzt eine passable Lösung eingefallen.
Die Vektoren in der Liste mögen kleinstmögliche ganzzahlige Schenkel haben
und in dieser Liste sollen alle möglichen Vektoren enthalten sein, die derart darstellbar sind.
Damit brauche ich bloß den Vektor aus dem beliebigen Bruch,
soweit durch Division verkleinern, runden und ganzzahlig darstellen,
dass ich durch simples Vergleichen,
diesen beliebige Bruch einem Listenelement zuordnen kann.
Danke für die Diskussion
Erhy
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 16:50 Di 01.06.2021 | Autor: | Erhy |
Hallo!
Bin etwas enttäuscht über meine eigenen Mathematik Kenntnisse.
Mein erdachter Lösungsweg funktioniert nur mit Vektoren,
die aus den Randkoordinaten und dem Zentrum von einem Quadrat gebildet werden,
wenn das Quadrat aus 4 eingeschriebenen Quadraten besteht.
Besteht ein solches Quadrat aus 16 eingeschriebenen Quadraten erhoffte ich Winkeldifferenzen von 22,5 °.
Aber es ergeben sich Vektoren mit unterschiedlichen Winkeldifferenzen., aneinandergereiht:
26.6 18.4 18.4 26.6 26.6 18.4 ... Grad Differenz
Was ist Eure Meinung?
Genügt es die Präzision zu erhöhen, um in etwa den passenden Winkel aus der Liste auszuwählen? (Indem ich die Anzahl der eingeschriebenen Würfel erhöhe.)
Wie könnte ein Verfahren mit diskreten Winkeln sonst noch funktionieren?
Oder muss ich unbedingt die Trigonometrie bemühen.
Danke für Eure Meinung
Erhy
|
|
|
|
|
> Hallo!
> Bin etwas enttäuscht über meine eigenen Mathematik
> Kenntnisse.
>
> Mein erdachter Lösungsweg funktioniert nur mit Vektoren,
> die aus den Randkoordinaten und dem Zentrum von einem
> Quadrat gebildet werden,
> wenn das Quadrat aus 4 eingeschriebenen Quadraten
> besteht.
>
> Besteht ein solches Quadrat aus 16 eingeschriebenen
> Quadraten erhoffte ich Winkeldifferenzen von 22,5 °.
> Aber es ergeben sich Vektoren mit unterschiedlichen
> Winkeldifferenzen., aneinandergereiht:
> 26.6 18.4 18.4 26.6 26.6 18.4 ... Grad Differenz
>
> Was ist Eure Meinung?
Zur halben Höhe (y-Wert) bei gleicher Breite (x-Wert) eines Dreiecks gehört nicht der halbe Winkel. Wenn bei einer Uhr der große Zeiger von 12 auf 2 Uhr (60°) wandert und sich die Zeigerspitze z.B. um 12 cm absenkt, senkt sie sich anschließend von 2 auf 3 Uhr (30°) ebenfalls um 12 cm ab und nicht nur um 6 cm. Deshalb braucht man ja die trigonometrischen Funktionen. Evtl. kannst du aber sogar darauf verzichten (s.u.).
>
> Genügt es die Präzision zu erhöhen, um in etwa den
> passenden Winkel aus der Liste auszuwählen? (Indem ich die
> Anzahl der eingeschriebenen Würfel erhöhe.)
Aus all deinen bisherigen Fragen wird mir überhaupt nicht klar, welches Problem du überhaupt lösen willst. Erst waren es Brüche, dann Vektoren, vorher gingen sie irgendwo hin, jetzt zeigen sie auf den Rand eines Quadrats...
Woher kommen denn die Zahlen aus der Liste? Kannst du da nichts anderes wählen? Warum benutzt du ein Quadrat?
>
> Wie könnte ein Verfahren mit diskreten Winkeln sonst noch
> funktionieren?
>
> Oder muss ich unbedingt die Trigonometrie bemühen.
Im Diskussionsbaum unter "Beispiel nachgerechnet und OK" von dir findest du unter "Mitteilung" von mir nochmals eine vereinfachte Rechnung, bei der zum Schluss nur der cos vorkommt. Die kannst du auch auf Vektoren vom Mittelpunkt zum Rand des Quadrats anwenden, wenn du sie wieder als Brüche umschreibst. Empfehlung, falls du am liebsten mit ganzen Zahlen rechnen möchtest: Mach das Quadrat so groß, dass die Randpunkte ganzzahlig sind, die Vektorrichtung ändert sich nicht.
Beispiel für ein 4x4 Quadrat: Obere rechte Ecke 2/2, darunter 2/1, rechts 2/0, darunter 2/-1, rechte untere Ecke 2/-2 usw. als Bruch a/b in o.a. Mitteilung benutzen, damit die Brüche deiner Liste als jeweils A/B durchrechnen.
Nachtrag: Die "Brüche" sind eigentlich Vektorkomponenten, deshalb darf im "Nenner" auch 0 vorkommen. Nur 0/0 gibt keinen Sinn.
[mm] \fbox{Du kannst evtl. sogar auf den arccos verzichten: Aus der rechten Seite meiner Gleichung ergibt sich der cos des Differenzwinkels. Dieser ist um so KLEINER, je GRÖßER(!) der cos - also das Ergebnis - ist (bei negativen Werten ist er sogar über 90 °).}
[/mm]
>
> Danke für Eure Meinung
>
> Erhy
|
|
|
|
|
Status: |
(Frage) reagiert/warte auf Reaktion | Datum: | 18:04 Mi 02.06.2021 | Autor: | Erhy |
mein Ziel ist ein richtungsabhängiger Weichzeichner.
Habe im Foto eine Selektion in Form eines Bandes.
Nun soll in senkrechter Richtung im Verlauf des Bandes weichgezeichnet werden.
Die Anzahl der programmatisch vorzubereitenden Filter möchte ich auf 16 beschränken,
was eine maximale Ungenauigkeit von 22,5 ° bedeutet.
Die Areale entlang des Bandes und die zugehörigen Ausrichtungen konnte ich bereits ermitteln.
Das hier angesprochene Thema betrifft die Zuordnung
eines Vektors der Band-Senkrechten
zu den dezidierten Winkeln der vorbereiteten Filter.
Diese Zuordnung möchte ich so effizient wie möglich verwirklichen.
Danke für Eure Geduld
Erhy
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 18:50 Mi 02.06.2021 | Autor: | chrisno |
Darum habe ich die Tabelle vorgeschlagen. Die muss nur einmal (wenn sich nicht noch etwas anderes ändert) berechnet werden. Danach kommt nur noch eine Reihe von Größenvergleichen, bis der richtige Winkel gefunden ist.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 14:10 Do 03.06.2021 | Autor: | Erhy |
findet ihr das brauchbar:
von dem beliebigen Vektor
zuerst den Quadranten mit sign(Vektorkomponent[i]) bestimmen,
dann das 45 ° Segment durch Vergleich des Verhältnisses der Vektorkomponenten > <= 1 auswählen.
zuletzt die im 45 ° Segment verbleibenden Listen-Vektoren
derart bestimmen, indem die Abstände der
Endpunkte dieser Vektoren zum Endpunkt des beliebigen Vektors ermittelt wird
und mit dem kleinsten dieser Abstände der Listen-Vektor ausgewählt wird.
Für die Abstände bräuchte man nur die Hypotenuse-Formel.
Übrigens interessiert mich nur die Ausrichtung der beliebigen Vektoren -
beim Weichzeichnen würden folgende Vektoren gleich behandelt werden:
z.B 1,5 ; -1,-5
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 08:28 Fr 04.06.2021 | Autor: | chrisno |
> findet ihr das brauchbar:
> von dem beliebigen Vektor
>
> zuerst den Quadranten mit sign(Vektorkomponent) bestimmen,
>
> dann das 45 ° Segment durch Vergleich des Verhältnisses
> der Vektorkomponenten > <= 1 auswählen.
>
soweit ok
> zuletzt die im 45 ° Segment verbleibenden Listen-Vektoren
> derart bestimmen, indem die Abstände der
> Endpunkte dieser Vektoren zum Endpunkt des beliebigen
> Vektors ermittelt wird
>
> und mit dem kleinsten dieser Abstände der Listen-Vektor
> ausgewählt wird.
>
Das setzt voraus, dass die Vektoren in etwa alle die gleiche Länge haben.
Da müssten Beispiele und insbesondere die Extremfälle gerausgesucht werden.
> Für die Abstände bräuchte man nur die
> Hypotenuse-Formel.
>
> Übrigens interessiert mich nur die Ausrichtung der
> beliebigen Vektoren -
> beim Weichzeichnen würden folgende Vektoren gleich
> behandelt werden:
> z.B 1,5 ; -1,-5
>
Für ein weichzuzeichnendes Band muss diese Rechnung nur einmal ausgeführt werden. Da ist eine arctan Rechnung doch kein Problem für die Effizienz.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 13:44 Sa 05.06.2021 | Autor: | Erhy |
Habe nochmal darüber geschlafen und es ist mir eingefallen:
Wenn ich gemäß der Abstufung in Graden vorab
eine Liste von Tangenswerten erstelle,
brauche ich nur den Quotienten der Vektorkomponenten
einem Bereich der Liste zuordnen.
Natürlich mit der Ausnahme-Behandlung bei Division durch 0.
(das wäre quasi eine diskrete ArcTan-Funktion.)
Ob ich vorab die Quadranten bestimmen muss, werde ich noch überlegen.
Gruß
Erhy
|
|
|
|
|
Eine tan-Liste hilft dir nicht weiter, du musst schon eine Gradliste aufstellen.
Beispiel: In der tan-Liste stehen die Werte 0,84 und 5,76. Du vergleichst mit 2,5 und stellst fest, dass dieser Wert 1,66 von 0,84 und 3,26 - also ca. doppelt so weit - von 5,76 entfernt ist. Also nimmst du den ersten Wert als kleinsten Abstand.
Die Winkel hierzu heißen aber
arctan(0,84)=40°
arctan(2,5)= 68°
arctan(5,76)=80°
und der Abstand zum ersten Winkel ist mit 28° mehr als doppelt so groß wie zum zweiten mit 12°.
Wenn du unbedingt mit einer Vergleichsliste arbeiten willst, nimm auf jeden Fall eine Grad-Liste!
Das Problem mit der Null im Nenner und den Quadranten kannst du auf folgende Weise umgehen:
Alle Winkel werden von der positiven x-Achse berechnet, und zwar mit der für (1|0) vereinfachten cos-Formel (keine Probleme mit 0 im Nenner!):
Für (a|b) gegen (1|0) [mm] cos(\alpha)=\bruch{a}{\wurzel{a^2+b^2}}.
[/mm]
arccos gibt dann den Winkel zwischen dem Vektor und der x-Achse an, von 0 bis 180°. Es wird aber nicht unterschieden, ob links- oder rechtsdrehend von der positiven x-Achse aus. Das lässt sich nun einfach korrigieren: Falls b negativ ist, geht der Vektor nach unten, deshalb machst du ein Minuszeichen vor den Winkel (Rechtsdrehung) und erhältst nun insgesamt Werte von -180° bis 180°.
Nimm jetzt den Vektor, den du mit der Tabelle vergleichen willst. Den Winkel dazu berechnest du genau wie oben und korrigierst ggf. mit einem Minuszeichen.
Beim Vergleich mit einem Tabellenwert gehst du so vor:
Berechne die Differenz zwischen dem Winkel und dem Tabellenwert. Nimm davon den Betrag. Ist der Wert>180°, ziehst du ihn von 360° ab.
Beispiel: (-30°)-(170°)=-200° [mm] \mapsto [/mm] +200°>180° [mm] \mapsto [/mm] 360°-200°=160°
Da du bisher auf meine Beiträge nicht reagiert hast und offenbar nicht von einer tan-Tabelle abrücken willst, ist dies mein letzter Beitrag zu diesem Thema.
|
|
|
|
|
Status: |
(Frage) reagiert/warte auf Reaktion | Datum: | 16:23 Mo 07.06.2021 | Autor: | Erhy |
habe nun die Tan-Listen Methode statistisch verifiziert.
Die Methode kommt mir sehr entgegen, da sie unabhängig von der
Ausrichtung z.B. ( 3, -5 ) , ( -3, 5 ) das selbe Ergebnis liefert,
was für das gerichtete Weichzeichnen ausreichend ist.
Habt ihr noch Verbesserungsvorschläge?
Den gesamten Python Code dazu findet ihr hier:
https://gitlab.com/Erhy/discrete-orientations/-/blob/main/discrete%20orientations.py
Kurzfassung:
Erstellen der Tangens Liste z.B. mit
degTanVals = [] # list of degrees with their tangens
for deg in np.arange( -60., 90. - 0.01 , 30. )
degTanVals.append( [mm] \
[/mm]
[ deg, ( np.tan( np.radians( deg ))) ] )
degVarr = np.asarray([li[0] for li in degTanVals])
tanVarr = np.asarray([li[1] for li in degTanVals])
mit den ermittelten Indices werden diese Werte zurückgegeben:
degsForFilter = np.empty((degVarr.shape[0]+1))
degsForFilter[0] = degMidDiff + degsAround[0]
degsForFilter[1:] = degVarr + degMidDiff # each element in degVarr added by ...
Anwendung für Vektor fromThisVector :
if fromThisVector[1] != 0 :
q = fromThisVector[0] / fromThisVector[1]
pin = np.searchsorted( tanVarr, q )
else :
pin = pinMinMax[1] if fromThisVector[0] > 0 else 0
degCalculated = degsForFilter[pin] # calculated angle for blur-filter
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 22:15 Mo 07.06.2021 | Autor: | chrisno |
Hi,
meine Begegnung mit Python war nur kurz. Daher bin ich nicht der Richtige, um den Code im Detail auf mögliche Probleme zu untersuchen.
Einen Engel kannst du noch in einen Winkel verwandeln, der englische Tangens endet mit einem t und andere Kleinigkeiten im Englischen. Das aber hat nichts mit der Funktion des Codes zu tun.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 17:11 Sa 12.06.2021 | Autor: | Erhy |
wurde doch von chrisno ausreichend beantwortet
und ich bin mit dem Ergebnis zufrieden.
Wenn ich auch letztendlich selber den für mich optimalen Lösungsweg gefunden habe, dann auf Grund der umfangreichen Diskussion und der vielen Zwischenlösungen.
Erhy
|
|
|
|
|
Da ich mich mit Weichzeichnern nicht auskenne und immer noch nicht genau weiß, was du brauchst (Abstände, Winkel,...?) hier noch mal ein Beispiel, dass dir vielleicht weiter hilft. Nicht nötig sind Quadranten, Signum-Fkt. usw. Es spielt auch keine Rolle, wie lang die Vektoren sind.
[Dateianhang nicht öffentlich]
Das Bild zeigt ein Feld von Pixeln. Das gelbe ist das Bezugsfeld (0|0), das blaue A(3|4) das zu untersuchende. Nun suchst du dir von (0|0) aus andere Felder aus (ich habe hier 4 ausgewählt, zu denen die roten Linien führen) und willst den Winkel zwischen den roten Linien und der grünen minimieren.
Man sieht, dass das hier die Linie zu (2|3) sein wird.
Rechnung für den Winkel zwischen Linie nach (a|b) und (A|B):
[mm] \bruch{a*A+b*B}{\wurzel{a^2+b^2}*\wurzel{A^2+B^2}}
[/mm]
(2|3) und (3|4): [mm] \bruch{2*3+3*4}{\wurzel{2^2+3^2}*\wurzel{3^2+4^2}}=\bruch{18}{\wurzel{13}*\wurzel{25}}= [/mm] 0,99846 (größtes Ergebnis, kleinster Winkel)
(2|2) und (3|4): [mm] \bruch{2*3+2*4}{\wurzel{2^2+2^2}*\wurzel{3^2+4^2}}=\bruch{14}{\wurzel{8}*\wurzel{25}}= [/mm] 0,98995
(0|4) und (3|4): [mm] \bruch{0*3+4*4}{\wurzel{0^2+4^2}*\wurzel{3^2+4^2}}=\bruch{16}{\wurzel{16}*\wurzel{25}}= [/mm] 0,80000
(-2|-1) und (3|4): [mm] \bruch{-2*3-1*4}{\wurzel{(-2)^2+(-1)^2}*\wurzel{3^2+4^2}}=\bruch{-10}{\wurzel{5}*\wurzel{25}}= [/mm] -0,89443 (kleintes Ergebnis, größter Winkel; negatives Ergebnis bedeutet über 90°)
Wendest du den arccos auf die Ergebnisse an, erhältst du die Winkel 3,18°, 8,13°, 36,87° und 153,4°.
Ist die Gegenrichtung zur normalen Richtung gleichwertig, nimmst du statt -0,89443 den positiven Wert 0,89443 und ordnest ihn ein (26,56°).
Bei diesem Rechenverfahren werden die verschiedenen Vektorlängen durch die Wurzeln im Nenner berücksichtigt.
Dateianhänge: Anhang Nr. 1 (Typ: JPG) [nicht öffentlich]
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 22:11 Fr 28.05.2021 | Autor: | chrisno |
Wie in anderen Programmiersprachen gibt es auch in Python die passende Arcustangensfunktion mit zwei Argumenten:
numpy.arctan2()
Die liefert dir den Winkel im richtigen Quadranten und das Problem mit der Division durch Null ist auch weg.
|
|
|
|
|
Die Hürden bei dieser Aufgabe sind:
Der Nenner kann 0 sein.
Nenner, die gleich 0 sind, darf man doch wohl einfach ausschließen, wenn es darum gehen soll, damit Brüche zu bilden.
Nebenbei: In der Überschrift der Aufgabe steht etwas von "ganzzahligen Brüchen" - gemeint hast du aber wohl Brüche mit ganzzahligen Zählern und Nennern. Das ist keineswegs dasselbe.
|
|
|
|
|
Ja, das fiel mir erst später ein. Es handelt sich bei meiner Darstellung um die Bruchschreibweise, weil Erhy anfangs von Brüchen sprach und sich wohl mit Vektoren bzw. Vektorrechnung nicht gut auskennt. Tatsächlich sind bei meinen "Brüchen" zweidim. Vektoren gemeint. Hier darf also im Pseudo-Nenner auch 0 stehen, nun bei 0/0 kommt nichts Gescheites heraus.
Mit ganzzahlig meinte ich natürlich ganzzahlige Koordinaten der Vektoren.
|
|
|
|