Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Mär 28, 2024 21:32

Foren-Übersicht » Programmierung » Mathematik-Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Skalierung mittels Quaternion
BeitragVerfasst: Mo Mai 26, 2014 22:18 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Ich möchte in einem Quaternion Skalierung unterbringen. Dies ist laut dieser Seite möglich:
euclidean space hat geschrieben:
In fact quaternions can represent 3D reflections, rotations and scaling
Leider steht da nicht (für mich verständlich) wie.

Also ich suche ein Quaternion Q (groß geschrieben), so dass gilt:
Code:
  1. Q * v = f * v  // v: Vektor,  f: Skalierungsvektor
Die Multiplikation f*v ist komponentenweise gemeint, wie in GLSL.

Da ich nichts Sinnvolles dazu im Web gefunden habe, habe ich versucht, mir das selbst herzuleiten. Dummerweise endete der Versuch in einem mathematischen Widerspruch :/
Hier mal meine Überlegungen:
Code:
  1. // Variablen
  2. Quaternion x*i +y*j +z*k +w   // i,j,k sind imaginär
  3. Ausgangsvektor v mit v.x = p,  v.y = q,  v.z = r
  4. Ergebnisvektor e der Multiplikation Quaternion * Ausgangsvektor
  5.  
  6. // Bekannt und erprobt ist folgende Formel:
  7. e = v + 2 * cross((x,y,z),  cross((x,y,z), v) + w*v)
  8.  
  9. // Schritt für Schritt lässt sie sich aufdröseln:
  10. e = v + 2 * cross((x,y,z),  cross((x,y,z), v) + w*v)
  11. e = v + 2 * cross((x,y,z),  a                 + w*v)
  12. e = v + 2 * cross((x,y,z),  b)
  13. e = v + 2 * c
  14. e = v + d
  15.  
  16. // a = cross((x,y,z), v)
  17. a.x = y*r - z*q
  18. a.y = z*p - x*r
  19. a.z = x*q - y*p
  20.  
  21. // b = a + w*v
  22. b.x = y*r - z*q + w*p
  23. b.y = z*p - x*r + w*q
  24. b.z = x*q - y*p + w*r
  25.  
  26. // c = cross((x,y,z),  b)
  27. c.x = y*(x*q - y*p + w*r) - z*(z*p - x*r + w*q)
  28. c.y = z*(y*r - z*q + w*p) - x*(x*q - y*p + w*r)
  29. c.z = x*(z*p - x*r + w*q) - y*(y*r - z*q + w*p)
  30.  
  31. // d = 2*c
  32. d.x = 2*(y*(x*q - y*p + w*r) - z*(z*p - x*r + w*q))
  33. d.y = 2*(z*(y*r - z*q + w*p) - x*(x*q - y*p + w*r))
  34. d.z = 2*(x*(z*p - x*r + w*q) - y*(y*r - z*q + w*p))
  35.  
  36. // Endergebnis
  37. e.x = p + 2*(y*(x*q - y*p + w*r) - z*(z*p - x*r + w*q))
  38. e.y = q + 2*(z*(y*r - z*q + w*p) - x*(x*q - y*p + w*r))
  39. e.z = r + 2*(x*(z*p - x*r + w*q) - y*(y*r - z*q + w*p))
  40.  
  41.  
  42. // Wir betrachten nochmal Zeile 13:
  43. e = v + 2 * c
  44. // Mit etwas Überlegung oder durch Ausprobieren kommt man darauf, dass gilt:
  45. Skalierung um Vektor f wird erreicht  :<=>
  46. e = f * v   <=>
  47. c = ((f-1)/2)*v
  48.  
  49. // Nun betrachtet man nochmal Zeilen 27-29 und schaut nach, welcher Faktor vor v = (p,q,r) steht.
  50. //=> für c.x-Komponente ist das -y*y -z*z, also:
  51. -y*y -z*z           = (f.x-1)/2
  52.  y*x +y*w +z*x -z*w = 0   // Rest muss 0 sein
  53.  
  54. //=> für c.y-Komponente:
  55. -z*z -x*x           = (f.y-1)/2
  56.  z*y +z*w +x*y -x*w = 0
  57.  
  58. //=> für c.z-Komponente:
  59. -x*x -y*y           = (f.z-1)/2
  60.  x*z +x*w +y*z -y*w = 0

Das sieht ja erstmal ganz brauchbar aus. Bei genauerem Hinsehen ist dies jedoch eine Sackgasse (Zeile 51):
z*z und x*x sind immer nichtnegativ. Daher kann der Term -z*z -x*x niemals positiv sein. Wenn ich um 5 skalieren möchte, ist jedoch die rechte Seite = (5-1)/2 = 2 > 0.

Ich sehe in meinen Umformungen keinen Fehler (vielleicht ja einer von euch). Deswegen habe ich den Verdacht, dass die Ausgangsformel vielleicht nur zur Anwendung von Rotation durch ein Quaternion geeignet ist? Im Wiki gibt es jedenfalls noch eine andere Berechnungsmethode namens "Apply", die das gleiche tun soll. Übertragen auf meine Variablennamen tut diese Funktion folgendes:
Code:
  1. e.x = p * (w*w + x*x - y*y - z*z) + 2 * (x*y*q + x*z*r + w*y*r - w*z*q)
  2. e.y = q * (w*w - x*x + y*y - z*z) + 2 * (x*y*p + y*z*r + w*z*p - w*x*r)
  3. e.z = r * (w*w - x*x - y*y + z*z) + 2 * (x*z*p + y*z*q - w*y*p + w*x*q)
Und hier stehe ich leider etwas auf dem Schlauch. Intuitiv kann ich da weder rauslesen, wie man nun Skalierung im Quaternion unterbringt, noch sehe ich eine gescheite Möglichkeit, etwas auszuklammern oder sonstwie umzuformen, so dass man damit weiterarbeiten kann.

Hat jemand eine Idee (oder Lösung :wink: )?

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Skalierung mittels Quaternion
BeitragVerfasst: Mo Mai 26, 2014 22:58 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
glAwesome hat geschrieben:
Und hier stehe ich leider etwas auf dem Schlauch.
Naja, eigentlich ist der nächste Schritt offensichtlich. Was man manchmal für ein Brett vor dem Kopf hat... :lol:

Code:
  1. //    v *        f                +   0
  2. e.x = p * (w*w + x*x - y*y - z*z) + 2 * (x*y*q + x*z*r + w*y*r - w*z*q)
  3. e.y = q * (w*w - x*x + y*y - z*z) + 2 * (x*y*p + y*z*r + w*z*p - w*x*r)
  4. e.z = r * (w*w - x*x - y*y + z*z) + 2 * (x*z*p + y*z*q - w*y*p + w*x*q)
  5.  
  6. // Daraus ergibt sich:
  7. f.x = w*w +x*x -y*y -z*z
  8. x*y -w*z = 0  // q darf keinen Einfluss auf e.x haben
  9. x*z +w*y = 0  // r darf keinen Einfluss auf e.x haben
  10.  
  11. f.y = w*w -x*x +y*y -z*z
  12. x*y +w*z = 0  // p darf keinen Einfluss auf e.y haben
  13. y*z -w*x = 0  // r darf keinen Einfluss auf e.y haben
  14.  
  15. f.z = w*w -x*x -y*y +z*z
  16. x*z -w*y = 0  // p darf keinen Einfluss auf e.z haben
  17. y*z +w*x = 0  // q darf keinen Einfluss auf e.z haben
Die Formel aus dem Wiki ist nichts weiter als eine Kombination aus In-Matrix-umwandeln und Matrixmultiplikation.

Wie ich jetzt an Werte für x, y, z und w komme, weiß ich zwar immer noch nicht, aber vielleicht kommt das noch... Denkanstöße sind natürlich weiterhin willkommen.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Skalierung mittels Quaternion
BeitragVerfasst: Di Mai 27, 2014 09:22 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
Wie man sieht, haben folgende Gleichungen große Ähnlichkeiten:
Code:
  1. f.x = w*w +x*x -y*y -z*z
  2. f.y = w*w -x*x +y*y -z*z
  3. f.z = w*w -x*x -y*y +z*z

Um die Gemeinsamkeiten zu eliminieren, subtrahieren wir doch mal ein bisschen:
Code:
  1. f.x - f.y = (w*w +x*x -y*y -z*z) - (w*w -x*x +y*y -z*z)
  2.           = 2*x*x - 2*y*y
  3. f.x - f.z = (w*w +x*x -y*y -z*z) - (w*w -x*x -y*y +z*z)
  4.           = 2*x*x - 2*z*z
  5. f.y - f.z = (w*w -x*x +y*y -z*z) - (w*w -x*x -y*y +z*z)
  6.           = 2*y*y - 2*z*z

Igitt, so viele quadratische Gleichungen!
Code:
  1. // substitution: x*x -> a,  y*y -> b,  z*z -> c
  2. f.x - f.y = 2*a - 2*b
  3. f.x - f.z = 2*a - 2*c
  4. f.y - f.z = 2*b - 2*c
  5.  
  6. // bzw.
  7. (f.x-f.y)/2 = a - b
  8. (f.x-f.z)/2 = a - c
  9. (f.y-f.z)/2 = b - c

Jetzt sind es 3 lineare Gleichungen mit 3 Unbekannten (Hurra!). Hat man ja schon zigfach durchexerziert... ähm... nanu... Diese ist allerdings verzwickt. *grübel*
Egal, welche Zeile man zu welcher addiert/subtrahiert: Man kann zwar einzelne Variablen eliminieren, jedoch kommt jedesmal eine andere hinzu. Ich fing schon an, an meinem Verstand zu zweifeln. Dann habe ich für f.x, f.y unf f.z einfach mal konkrete Werte (1, 2, 3) eingesetzt und das komplette lineare Gleichungssystem in meinen Taschenrechner getippt. Wenn der zu einer Lösung kommt, muss ich das schließlich auch schaffen.
Taschenrechner hat geschrieben:
Math ERROR

Aha! Dann liegt es wohl doch nicht an meiner geistigen Verwirrtheit. :wink: Kann man lineare Gleichungssysteme nicht lösen, wenn in jeder Gleichung eine andere Unbekannte den Koeffizienten 0 hat? Ich habe davon noch nie was gehört.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Skalierung mittels Quaternion
BeitragVerfasst: Mi Mai 28, 2014 11:32 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jun 05, 2013 15:12
Beiträge: 165
Wohnort: Glinde
Programmiersprache: Delphi 7
glAwesome hat geschrieben:
Q * v = f * v  // v: Vektor,  f: Skalierungsvektor


Huch...

'Q * v' ist das Gleiche wie 'f * v'
'v' umstellung um 'Q' zu bekommen wären dann doch

Code:
  1. f * v          
  2. ----- = Q  daher  Q = f
  3.   v  


Code:
  1.   v            
  2. ----- = Q  daher  Q = f
  3. f * v    



Code:
  1.  
  2. Q*v
  3. ---- = 0
  4. f*v


Da fehlt doch was anderes oder ?

@edit: Quaternion ist doch das drehen von Objekten. Also um welche Achse oder Grad (°) ?

_________________
幸福は笑う人に来て ~~ koufuku wa warau hito ni kite
Das Glück kommt zu denen die lachen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Skalierung mittels Quaternion
BeitragVerfasst: Mi Mai 28, 2014 17:10 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 587
Programmiersprache: C++
So einfach ist es nicht. Mit Q*v meinte ich die Anwendung der in Q gespeicherten Transformation auf v. Also eben die erwähnte Formel mit den verschachtelten cross-Funktionen
Code:
  1. e = v + 2 * cross((x,y,z),  cross((x,y,z), v) + w*v)
bzw. die Apply-Methode aus dem Wiki. Bei Q*v wird also nicht einfach komponentenweise Multiplikation angewandt (wäre auch nicht möglich, da Q 4dimensional und v 3dimensional ist). Das macht die Sache ja so kompliziert.

Polarwolf hat geschrieben:
Quaternion ist doch das drehen von Objekten.
Quaternionen können neben Drehung offenbar auch Skalierung speichern - um die geht's mir. Wie man Rotation im Quaternion unterbringt, ist ja gut dokumentiert.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Programmierung » Mathematik-Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 13 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.049s | 17 Queries | GZIP : On ]