• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

Bug bei Rotation ?

argus Portal

Freund/in des Forums
Hallo

Ich mache gerade eine ärgerliche Beobachtung und möchte wissen, ob dies ein Bug ist, oder ob es einen Grund für dieses Verhalten gibt:

Ich rotiere ein Objekt per llSetRot in 10-Grad-Schritten.

Prinzip:

vector testrotationv;
rotation rotr;
float winkel;

testrotationv.x = winkel;
testrotationv.y = 0.0;
testrotationv.z = 0.0;

llSetRot(llEuler2Rot(testrotationv*DEG_TO_RAD));


Bei jedem Schritt lese ich per llGetRot aus und erhöhe "winkel":

rotr = llGetRot();
llOwnerSay((string)(llRot2Euler(rotr) * RAD_TO_DEG));

winkel += 10.0;


Rotiere ich um die x- bzw. z-Achse, so zählt das Script von 0 bis 180 und dann mit negativen Werten zurück zu 0 Grad. Dabei bleiben die Angaben der beiden jeweils anderen Achsen auf 0 Grad. Die x- und z-Achsen verhalten sich also wie man es erwartet.


Anders bei Rotation um die y-Achse:

Hier kurz die Ausgabe des Scriptes:


<0.00000, 0.00000, 0.00000>
<0.00000, 10.00000, 0.00000>
<0.00000, 20.00000, 0.00000>
<0.00000, 30.00000, 0.00000>
<0.00000, 40.00000, 0.00000>
<0.00000, 50.00000, 0.00000>
<0.00000, 60.00000, 0.00000>
<0.00000, 70.00001, 0.00000>
<0.00000, 80.00001, 0.00000>
<0.00000, 90.00000, 0.00000>
<180.00000, 79.99999, 180.00000>
<180.00000, 69.99997, 180.00000>
<180.00000, 60.00000, 180.00000>
<180.00000, 50.00000, 180.00000>
<180.00000, 40.00000, 180.00000>
<180.00000, 30.00000, 180.00000>
<180.00000, 20.00001, 180.00000>
<180.00000, 10.00001, 180.00000>
<180.00000, 0.00000, 180.00000>
<180.00000, -10.00001, 180.00000>
<180.00000, -20.00001, 180.00000>
<180.00000, -30.00000, 180.00000>
<180.00000, -40.00000, 180.00000>
<180.00000, -50.00002, 180.00000>
<180.00000, -60.00000, 180.00000>
<180.00000, -70.00001, 180.00000>
<180.00000, -79.99999, 180.00000>
<0.00000, -90.00000, 0.00000>
<0.00000, -80.00001, 0.00000>
<0.00000, -70.00001, 0.00000>
<0.00000, -60.00001, 0.00000>
<0.00000, -50.00000, 0.00000>
<0.00000, -40.00001, 0.00000>
<0.00000, -30.00002, 0.00000>
<0.00000, -20.00001, 0.00000>
<0.00000, -10.00002, 0.00000>
<0.00000, 0.00000, 0.00000>


Was soll das bedeuten ? Wegen dieses Verhaltens komme ich gerade bei einem Projekt nicht weiter. Ich möchte möglichst einen Workaround vermeiden oder so einfach wie möglich gestalten.

Hat jemand eine Idee ?





Gruss
 
Dein Problem ist wohl die Art und Weise, wie die Quaternionen der Rotation durch llEuler2Rot in einen Eulerwinkel (3 Winkel für je eine Achse) für ein kartesisches Koordinatensystem (in dem alle 3 Achsen orthogonal zueinander stehen) umgerechnet werden. (Um umgekehrt durch llRot2Euler)

Im 3-Dimensionalen Raum hat man da eben das Problem, dass man dann, wenn man nur Eulerwinkel zur Angabe von Drehungen verwendet, zu dem Fall kommen kann, dass durch die Drehung ein nicht eindeutiges Ergebnis herauskommen kann. Das Problem dabei ist eben, dass Eulerwinkel im Prinzip drei nacheinander ablaufende Drehbewegungen um je eine Achse darstellen. Wobei sich das lokale Bezugssystem mitdreht. Und dadurch kann es bei einer entspechend großen Drehung eben zu dem Fall kommen, dass 2 Achsen aufeinander fallen, so dass eine Drehung nicht mehr eindeutig ist. Deswegen (unter anderem..) verwendet man in der PC-Grafik und in der Physik usw. meist eindeutige Quaternionen für Rotationen. Und so eben auch in SL. Eine Quaternion ist dabei eine Zahl aus 4 Bestandteilen, die damit im Prinzip eine 4-Dimensionale Beschreibung der Drehung im nur 3-Dimensionalen Raum ist. D.h. die Zahlen in der Quaternion sind eben nicht direkt irgendwelche Winkelangaben, bei der Rotation <x,x,y,s> ist s der "Realteil" der Drehung und <x,y,z> ist ein "imaginärer Vektor" (vergleichbar mit den imaginären Zahlen [1i = sqrt(-1)] )

Deswegen wird der Eulerwinkel <x,y,z> folgendermaßen von llEuler2Rot in eine Quaternion <a,b,c,s> umgewandelt:

Code:
//Definition für die Winkel laut LSL Wiki
v/=2;
rotation k = <0.0, 0.0, llSin(v.z), llCos(v.z)> * <0.0, llSin(v.y), 0.0, llCos(v.y)> * <llSin(v.x), 0.0, 0.0, llCos(v.x)>;

Also im Grunde sind das einfach erst mal Sinus- bzw. Kosinusfuntionen, die letztendlich wüst miteinander multipliziert und addiert werden (Stichwort: Multiplikation komplexer Zahlen, in diesem Fall gleich mit 4 Komponenten...). Und da hast du dann das Problem, dass sin(0) ==sin(Pi) == sin (2Pi) == 0 == Cos(1/2Pi) == Cos (3/2 Pi) == 0 ist. Das führt bei den Multiplikationen eben dazu, dass bestimmte Werte durch das Umrechnen eben mal auf 0 gehen können für bestimmte Rotationswinkel. Was leider nicht eindeutig ist. Deswegen dieses seltsame Verhalten.

Möglichkeiten um das Problem zu umgehen: Nicht um genau 90° drehen (was vermutlich keine wirkliche Lösung ist) oder eben nicht mit llEuler2Rot und Eulerwinkeln arbeiten, sondern nur mit Rotationen, d.h. etwa mit llAxisAngle2Rot, da gibst du eben die Drehachsen an und einen Winkel um den du drehst. Und als Ergebnis kriegst du die Rotation, mit der deine bisherige Rotation kombiniert werden muss um in die neue Position zu drehen. [Dabei muss man bedenken, dass das * keine "normale Multiplikation" ist, die Mulitiplikation von Quaternionen ist nicht kommutativ, d.h. rot1 * rot2 ist nicht identisch mit rot2 * rot1]

Generell sollte man beim Drehen so viel wie möglich nur mit Rotationen und so wenig wie nötig mit Eulerwinkeln machen, denn jedes mal, wenn man einen Eulerwinkel umrechnet kriegt man neben dem Problem der aufeinander Fallenden Bezugsachsen auch noch Rechenfehler/Genauigkeitsfehler durch die Umrechnung rein, die man ohne Umrechnung nicht in dem Maß hat.
 
Dein Problem ist wohl die Art und Weise, wie die Quaternionen der Rotation durch llEuler2Rot in einen Eulerwinkel (3 Winkel für je eine Achse) für ein kartesisches Koordinatensystem (in dem alle 3 Achsen orthogonal zueinander stehen) umgerechnet werden. (Um umgekehrt durch llRot2Euler)

.........

Möglichkeiten um das Problem zu umgehen: Nicht um genau 90° drehen (was vermutlich keine wirkliche Lösung ist) oder eben nicht mit llEuler2Rot und Eulerwinkeln arbeiten, sondern nur mit Rotationen, d.h. etwa mit llAxisAngle2Rot,

Erstmal Danke für die ausführliche Antwort. Da war einiges interessantes zu entdecken. Allerdings besteht das Problem nach wie vor.

llAxisAngle2Rot() habe ich nach dem Lesen hier ausprobiert: Gleiches Verhalten.

Das kleine Testscript war nur nötig, weil sich mein eigentliches Script seltsam verhielt und ich erstmal Zeit vergeudet hatte, den Fehler bei mir zu suchen. In dem Script rechne ich zwar einiges mit llSin / llCos und llAsin. Aber die Eulerfunktionen setze ich dort nirgends ein.

Ich sehe keinen Grund dafür, das die Y-Achse eine Sonderrolle spielen soll. Meine Frage hier im Forum soll erstmal klären, ob es sich um einen LindenLab-Bug handelt. Für mich sieht das so aus.

Man kann das sogar im Viewer beobachten:

1. Man rezze einen Würfel.

2. ... gehe in den Objekt-Dialog (Rechte Maustaste, "Bearbeiten", Reiter "Objekt"):

3. .. setze im Bereich "Rotation" z.b. 91 Grad für die Y-Achse

Resultat:

x: 180
y: 91
z: 180

Und das, nach dem vorher alle Felder auf 0 standen.

-> So verhält es sich NUR mit der y-Achse. x- und z-Achse verhalten sich, wie man es sowohl logisch als auch intuitiv erwartet.


Ich versuche nun, eine Funktion zu schreiben, mit der ich den eindeutigen Winkel für die y-Achse auslesen kann.
 
Die Funktion ist fertig und mein Projekt läuft weiter. Jetzt verhält sich alles so, wie es sein soll.

Da die Funktion sehr klein ist, gebe ich sie hier kurz weiter:


float get_y_vec2deg(vector rotv)
{
vector tpv;


tpv = rotv * RAD_TO_DEG;


if ((tpv.x == 0.0) && (tpv.z == 0.0))
{
return tpv.y;
}


if ((tpv.x == 180.0) && (tpv.z == 180.0))
{
if (tpv.y >= 0.0)
{
return (90.0 - tpv.y) + 90.0;
}
else
{
return -(180.0 + tpv.y);
}
}

llOwnerSay("Problem: Wert konnte nicht umgesetzt werden: "
+ (string) tpv);

return tpv.y;

} // Ende get_y_vec2deg
 
Der einfachste Weg eine Rotation zu definieren, ist über die Eulerwinkel: also hier bei einer Rotation von 10 Grad um die y-Achse <0,10,0> * DEG_TO_RAD, die mit llEuler2Rot in eine Rotation umgerechnet wird.

Diese Rotation wird dann mit der Rotation des Prims llGetRot() multipliziert (nicht addiert). Aber aufgepasst, die Reihenfolge entscheidet, ob die Rotation um das globale (World-) Koordinatensystem oder das lokale (Prim-) Koordinatensystem durchgeführt wird.

llGetRot()*llEuler2Rot(<0,10,0> * DEG_TO_RAD); // Rotation ums globale KS

llEuler2Rot(<0,10,0> * DEG_TO_RAD)*llGetRot(); // Rotation ums lokale KS

Mit llRot2Euler(llGetRot())*RAD_TO_DEG) kannst du hinterher anschauen, wie der Prim jetzt rotiert ist (im globalen KS). Aber wiederum Obacht, die Reihenfolge der Drehungen wie LL sie definiert ist 3-2-1; also erst um die z-Achse,
dann um Y, dann um X.

Die Eulerwinkel, so wie du es vorhast, besser nicht manipulieren. Ist auch gar nicht nötig.



Code:
    rotation rot     = llEuler2Rot(<0, 10, 0> * DEG_TO_RAD );
    //llSetRot(llGetRot()*rot);  //global 
    llSetRot(rot*llGetRot());    // local
    llOwnerSay((string)(llRot2Euler(llGetRot())*RAD_TO_DEG));
 
Genau das hier:
"Mit llRot2Euler(llGetRot())*RAD_TO_DEG) kannst du hinterher anschauen, wie der Prim jetzt rotiert ist (im globalen KS)." ist doch das Problem.
Statt auf <0,100,0> spuckt das eben <180,80,180> aus.

Das Problem hier ist dabei wohl lediglich die Umrechnung der Rotation in die Eulerwinkel über llRot2Euler. Und genau da kommt es eben durch die oben erwähnten Uneindeutigkeiten dazu, dass statt <0,100,0> eben <180,80,180> raus kommt. Was aber hier die selbe Drehung ist, da sich bei der Rotation die lokalen Rotationsachsen, um die im nächsten Schritt gedreht wird, jeweils mitdrehen.
(Das Prim dreht sich in allen Achsen völlig korrekt mit dem Script von oben, auch in der y-Achse).

Auch ein Problem im Thread ist hier, dass der Ersteller nicht wirklich schreibt was genau sein Problem mit dem Umspringen von <0,90,0> auf <180,80,180> statt auf <0,100,0> ist.
 
Ich denke das Verstaendniss-Problem liegt nicht an den Rotationen selber, sondern an der Menschlichen Denkweise.
So wie ich das sehe, geht der Server grundsaetzlich von einer Geraden aus, und nicht wie in unseren Koepfen von einem 360° Kreis, wenn wir Winkel berechnen.
Von daher rechnet der Server immer von 180° (Gerade).

Ein ganz einfacher Test dazu bietet das Baumenue.
Wenn ich im Baumenue den Winkel Y langsam mit dem Scrollrad der Maus erhoehe, dreht sich der Wuerfel rechts herum.
Drehe ich ueber die 90° Marke hinaus, veraendern sich die beiden anderen Winkel ploetzlich von 0° auf 180°.
Jetzt wird es interessant, will ich den Wuerfel jetzt weiter in die gleiche Richtung drehen, muss ich auf einmal im Baumenue rueckwaerts scrollen und die werte von 90° auf 0° zurueck drehen, damit der Wuerfel entgueltig auf dem Kopf steht.

LG
Dae
 
Das hat wohl wie gesagt mit dem Sinus bzw. Arkussinus zu tun, und deren Periode für Sinuswerte.
Die Funktion llRot2Euler kriegt eben irgendwann einen nicht eindeutigen Winkelwert für einen Sinuswert und muss sich daher für 0 oder 180 entscheiden. Hier entscheidet sie sich bei der y-Achse warum immer für 180, und deshalb sind die beiden anderen Winkel auch nicht 100 und 0, sondern eben 80 und 180. Das ist am Ende aber eine identische Drehung.
 
Rotationen ist so Thema, das man auch nach Jahren nicht kapieren kann, mir geht es zumindest so. Aber ich denke das Problem bzw Erklärung von Shirley hat etwas mit diesem Phänomen zu tun:

Gimbal Lock

Eulerwinkel wie kardanische Aufhängung entsprechen drei nacheinander ausgeführten Drehungen, wobei die Drehachse jeweils von den vorherigen Drehungen mitbestimmt wird. Das Problem entsteht dadurch, dass die Achse der ersten Drehung und die der dritten zusammenfallen können. Dann ist nur noch die Summe aus erstem und drittem Winkel ausschlaggebend, verschiedene Kombinationen ergeben also dieselbe Drehung.

Man kann sowas prima beobachten wenn man auf ein Objekt von oben schaut, bei kleiner Bewegung der Camera dreht sich die Szene plötzlich um 180°.
 
Auch ein Problem im Thread ist hier, dass der Ersteller nicht wirklich schreibt was genau sein Problem mit dem Umspringen von <0,90,0> auf <180,80,180> statt auf <0,100,0> ist.

Wie meinen ?

Ich denke, das habe ich deutlich formuliert. Ich habe Berechnungen ausgeführt, die für die x und die z-Achsen funktionierten. Und bei der y-achse erhielt ich plötzlich sonderbare Resultate. Meine Frage hier war, ob das ein Bug ist. Und ich sage: Es ist ein Bug. Grosszügig könnte man auch von einer Design-Schwäche sprechen.

Nochmal: Weil llGetRot (ungeachtet der eulerschen Umrechungen) sich nicht einheitlich verhält. Und das sollte es aber. Das war das Problem.

Mein Beispiel für den Viewer zeigt denen, die interessiert sind, das die y-achse bei Lindenlabs eine Sonderrolle spielt.

Mit meiner Workaround-Funktion weiter oben konnte ich das Problem lösen. Ist das tatsächlich nicht deutlich geworden, worum es hier geht ?

Wenn man dieses seltsame Verhalten, das unlogisch ist, nicht kennt, vergeudet man erstmal Zeit weil: x funktioniert wie erwartet. z funktioniert wie erwartet: y : Nichts geht mehr.





Shirley, wenn das jetzt immer noch nicht deutlich war, gebe ich auf ;-)
 
Wie meinen ?

Ich denke, das habe ich deutlich formuliert. Ich habe Berechnungen ausgeführt, die für die x und die z-Achsen funktionierten. Und bei der y-achse erhielt ich plötzlich sonderbare Resultate. Meine Frage hier war, ob das ein Bug ist. Und ich sage: Es ist ein Bug. Grosszügig könnte man auch von einer Design-Schwäche sprechen.

Es ist nicht wirklich ein Bug, weil die Resultate korrekt sind. Die Rotation <0,100,0> ist nun mal identisch mit der Rotation <180,80,180>.
Und du hast nicht gesagt, was für dich das Problem an dieser Rotation ist. Sondern nur dass die Rotation nicht als <0,100,0> sondern als <180,80,180> angegeben wird.

Nochmal: Weil llGetRot (ungeachtet der eulerschen Umrechungen) sich nicht einheitlich verhält. Und das sollte es aber. Das war das Problem.

Warum genau sollte die Ausgabe einheitlich sein?
(Die Funktion soll schließlich einfach eine korrekte Umrechnung der Quaternion in Eulerwinkel liefern, und eben das tut sie ja auch...)
 
llgetRot liefert zunächst nur ein Quaternion zurück.

Vielleicht nochmal: Findest du es in Ordnung bzw.nicht verwirrend, wenn sich zwei Achsen logisch/intuitiv verhalten und die übrige davon nicht ? Fakt ist, das meine Berechnungen im Falles der Y-Achse einen falschen Wert lieferten. Und nicht bei den beiden anderen Achsen. Ich nenne das zumidnest eine Desigschwäche.

Und ohne meinen Workaround kann ich bestimmte Dinge nicht berechnen.


Hier der Ausschnitt, der Probleme macht(e). Du siehst, da kommt kein eulerscher Winkel vor.

(Sorry für die verlorengegangene Einrückung. Der wysiwyg-Editor funktioniert nicht (kann auch am Opera liegen))


float calc_sinus_eckpunkt(float gegenkathete,float ankathete)
{
float hypotenuse;
hypotenuse = calc_diagonale(gegenkathete,ankathete);
return gegenkathete / hypotenuse;
}

float calc_cosinus_eckpunkt(float gegenkathete,float ankathete)
{
float hypotenuse;
hypotenuse = calc_diagonale(gegenkathete,ankathete);
return ankathete / hypotenuse;
}


float calc_diagonale(float a,float b)
{
float tpa;
float tpb;
float sum;
tpa = a * a;
tpb = b * b;
sum = tpa + tpb;

return llSqrt(sum);
} // Ende calc_diagonale





// Rotation um Y-Achse :
sinus_eckpunkt = calc_sinus_eckpunkt(halbsize_z,halbsize_x);
resultierender_winkel = roty - llAsin(sinus_eckpunkt);
sinus_resultierender_winkel = llSin(resultierender_winkel);
cosinus_resultierender_winkel = llCos(resultierender_winkel);
diagonale = calc_diagonale(halbsize_x,halbsize_z);

zusatz_fuer_y_achsenrot.x = cosinus_resultierender_winkel * diagonale;
zusatz_fuer_y_achsenrot.y = 0.0;
zusatz_fuer_y_achsenrot.z = sinus_resultierender_winkel * diagonale;





Die Berechnung ist Teil eines grösseren Scriptes und der Sinn ist für die Fragestellung hier unwichtig.

Ich erwarte zunächst, das sich Funktionen einheitlich verhalten. Wenn ich mit meinem Auto unterwegs bin, möchte ich auch nicht erleben, dass das Lenkrad plötzlich seine Funktion ändert nur weil ich den Blinker setze.

Und genau so kommt mir das ganze hier vor.

(Nicht wundern über meinen grosszügigen Umgang mit Zwischenvariablen. LSL bietet immer wieder Überraschungen bei komplexeren Aufrufen. Ich arbeite in C und musste mir die dort mögliche knappe Formulierung hier in LSL erstmal abgewöhnen)
 
Das ist kein Problem mit der Funktion in LSL, das ist ein prinzipielles mathematisches Problem.

Für die Festlegung einer Drehung im karteischen 3D-Raum (d.h. bei dem die Achsen orthogonal aufeinander stehen) gibts prinzipiell mehrere Möglichkeiten:
a) Mit einem Quaternion, das im Wesentlichen eine reale Größe, verbunden mit der Drehung eines imaginären Koordinatensystems zum Ausgangssystem ist. (Details zur Berechnung und Definition sprengen den Rahmen hier, das passt eher in eine Vorlesung für höhere Mathematik...)

b) über die Angabe von drei Drehwinkeln in Bezug auf das kartesiche Ausgangskoordinatensystem, d.h. ein Winkel in Bezug zur x-Achse, einer zur y-Achse, einer zur Z-Achse. Dieses Winkel nennt man auch Eulerwinkel, und das System ist das, was du in deinem Script letztendlich auch verwendest: Winkel in Bezug auf je eine Achse.

[Daneben gibt es z.B. auch noch die Möglichkeit über Drehmatrizen zu arbeiten, aber wenn man mit den 3x3 Matrizen arbeitet kann man zwar auch in anderen Koordinatensystemen arbeiten (und mit Vektoren), muss sich aber leider mit 9 Variablen herumärgern.]

Jedenfalls besteht die Drehung á la Euler eben nicht nur aus einer einzelnen Zahl, sondern aus einem 3-Tupel, also 3 Zahlen, die direkt zusammengehören. In dem Fall, um den es hier geht ist das dann z.B. (0,100,0) und eben nicht nur 100.

In diesem Eulersystem mit den drei Winkeln gibts prinzipiell aber 2 Probleme:
a) Bei einer Drehung um 90° fallen die Achsen zusammen, dreht man die y-Achse um 90°, dann kommt die x-Achse auf die z-Achse. Womit zwischen der Drehung um die x- und zwischen der Rotation um die z-Achse nicht mehr unterschieden werden kann. D.h. das Ergebnis der weiteren Rotation ist eben nicht mehr eindeutig. (-> Gimbal Lock)

b) Dreghungen im kartesichen 3D-Raum sind nicht eindeutig einer einzigen Eulernotation zugeordnet.
Zwar führt jeder Eulerwinkel (a,b,c) zu genau einem einzigen Quaternion (x,j,k,l), aber zu einer eindeutigen Drehung kann es durchaus mehrere Eulerwinkel (a1,b1,c1) = (a2,b2,b3) = ...= (an,bn,cn) geben, so dass alle diese EulerwinkelDarstellungen ein und der selben Drehung sind. (0,100,0) ist so eben absolut identisch mit (180,80,180).
Wenn man diese Quaternion in die Eulernotation mit ihren Winkelangaben transformieren will, nämlich über llRot2Euler, gibt es mehrere mögliche Resultate. Und das aus dieser Funktion stammende Resultat (180,80,180) ist eben eines davon. Das ist nur nicht ganz so intuitiv wie (0,100,0).

Beim Auto ändert sich da also nicht die Funktion des Lenkrads, wenn du den Blinker setzt. Um in einem regelmäßigen Gitter von einem Eckpunkt zum anderen zu kommen gibt es mehere optimale Wege. D.h. dein Navi kann dich eben nicht nur einen kürzesten Weg losten, sondern einen von mehreren möglichen, wenn du durch eine Gitter-Stadt wie Mannheim oder NewYork unterwegs bist.

[Wenn du einen bestimmten Winkel vor und nach einer Rotation auslesen willst solltest du eher Funktionen llRot2Left, llAngleBetween usw. anschauen, die arbeiten direkt mit Rotationen und geben eindeutige Orientierungsvektoren aus, mit deren Hilfe man dann die entsprechenden Winkel manuell und eindeutig berechnen kann. Allerdings solltest du bedenken, dass arcsin ebenso periodisch ist wie sin... und eben auch immer nur Werte aus bestimmten Bereichen ausspuckt. sin(0)= sin (180) = sin (360) = 0; arcsin(0) = 0, da der arcsin eben nur zwischen -Pi/2 und +Pi/2 definiert ist.]
 
Zuletzt bearbeitet:
In diesem Eulersystem mit den drei Winkeln gibts prinzipiell aber 2 Probleme:
a) Bei einer Drehung um 90° fallen die Achsen zusammen, dreht man die y-Achse um 90°, dann kommt die x-Achse auf die z-Achse. Womit zwischen der Drehung um die x- und zwischen der Rotation um die z-Achse nicht mehr unterschieden werden kann. D.h. das Ergebnis der weiteren Rotation ist eben nicht mehr eindeutig. (-> Gimbal Lock)

Hier hat es "Klick" gemacht. Das leuchtet ein und so habe ich das bisher nicht gesehen. Bleibt aber die Frage, warum die
"Verteilung der 3 Komponenten" zuverlässig nur bei der y-achse auftritt.

Würde sich das wie gesagt einheitlich verhalten, dann wäre ich zufriedener ;-) Oder gibt es einen speziellen Grund für die Sonderbehandlung der Y-Achse ? Denn dieses Problem, das sich die Achsen verlagern, betrifft alle drei Achsen gleichermassen. Drehe ich die x-Achse um 90 Grad, kommt die y-Achse auf die z-Achse: Gleiches Spiel !


Auf jeden Fall vielen Dank für deine ausführlichen Schilderungen !
 
Ich hab die mögliche Ursache für das Verhalten im Viewer Source gefunden:

Hier wird der y-Winkel einfach anders berechnet als der x- und der z-Winkel. Der Viewer (und vermutlich auch die LSL Funktion auf dem Server...) berechnet die Eulerwinkel über eine Rotationsmatrix aus der Quaternion (in llquaternion.cpp bzw. m3math.cpp im Sourcecode), dabei wird für getEulerAngles zuerst der Y-Winkel letztendlich über den Arkussinus aus der Rotationsmatrix berechnet, wobei die Matrizenwerte dafür zwischen -1 und 1 limitiert werden. Und erst dann werden (wieder aus der Rotationsmatrix) der Kosinus- und Sinuswert der X- und Z-Matrix berechnet. Und daraus dann mit der atan2 Funktion letztendlich der X- und der Z-Winkel. Dabei haben die beiden Funktionen asin und atan2 eben unterschiedliche Definitionswerte. asin ist nur definiert im Bereich [-1,1] und kann eben Werte zwischen -Pi/2 und Pi/2 annehmen, d.h. zwischen -90° und 90°. Die Funktion atan2 ist aber für alle Reellen Zahlen definiert und kann dabei normalerweise Werte zwischen -Pi und Pi annehmen, also zwischen -180° und 180°.

Deswegen nimmt in der Anzeige der x- und der z-Winkel Werte bis 180 an und der Y-Winkel nur Werte bis 90
 
Damit ist dieses Verhalten, das je nach Vorhaben wirklich ärgerlich ist, wenigstens erklärt. Der Thread hier hat sich schon mehrfach gelohnt. Danke nochmal für deine Unermüdlichkeit :thumbup
 

Users who are viewing this thread

Zurück
Oben Unten