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

Aktuelle Zeit: Mi Mai 15, 2024 09:30

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



Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Matrixrotation
BeitragVerfasst: Do Jun 17, 2010 01:31 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

ich schreib mir grad ne Methode, die eine Matrix rotieren soll, allerdings will es nich ganz so wie ich will. Hier erstma der Code, den ich bis jetzt hab:
Code:
/////////////////////////////////////////////////////////////////////////////////////////////////
//läd die Standartwerte einer Matrix
//@Matrix: Zeiger auf die Matrix die geladen werden soll;
procedure gluLoadMatrixIdentity(const Matrix: PgluMatrix);
begin
  Matrix^[maXAxis] := gluMatrixAxis(1, 0, 0, 0);
  Matrix^[maYAxis] := gluMatrixAxis(0, 1, 0, 0);
  Matrix^[maZAxis] := gluMatrixAxis(0, 0, 1, 0);
  Matrix^[maPos]   := gluMatrixAxis(0, 0, 0, 1);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////
//dreht die Matrix um die angegebene Achse bezüglich ihrer eigenen Achsen
//@Matrix: Matrix die gedreht werden soll;
//@Angle: Winkel um den gedreht werden soll (im Bogenmaß);
//@X: X-Wert der Achse um die gedreht werden soll;
//@X: Y-Wert der Achse um die gedreht werden soll;
//@X: Z-Wert der Achse um die gedreht werden soll;
procedure gluRotateMatrix(const Matrix: PgluMatrix; const Angle: Single; Axis: TglVector3f);
var
  RotMatrix: TgluMatrix;
  X, Y, Z: Single;
  a, c, s: Single;
begin
  gluNormalize(Axis);
  X := Axis[0];
  Y := Axis[1];
  Z := Axis[2];
  a := Angle/180*Pi;
  c := cos(a);
  s := sin(a);
  gluLoadMatrixIdentity(@RotMatrix);
  RotMatrix[maXAxis] := gluMatrixAxis(
    SQR(X) + (1-SQR(X))*c,
    X*Y*(1-c) + Z*s,
    X*Z*(1-c) - Y*s, 0);
  RotMatrix[maYAxis] := gluMatrixAxis(
    X*Y*(1-c) - Z*s,
    SQR(Y) + (1-SQR(Y))*c,
    Y*Z*(1-c) + X*s, 0);
  RotMatrix[maZAxis] := gluMatrixAxis(
    X*Z*(1-c) + Y*s,
    Y*Z*(1-c) - X*s,
    SQR(Z) + (1-SQR(Z))*c, 0);
  gluMatrixMul(Matrix, @RotMatrix);
end;

/////////////////////////////////////////////////////////////////////////////////////////////////
//Mutlipliziert Matrix1 mit Matrix2 und speichert das Ergebniss in Matrix1
//@Matrix1: 1. Multiplikator;
//@Matrix2: 2. Multiplikator;
procedure gluMatrixMul(const Matrix1, Matrix2: PgluMatrix);
type
  TMatrix = array[0..3, 0..3] of glFloat;
  PMatrix = ^TMatrix;
var
  x, y, i: Integer;
  sum : Single;
  M1, M2, MRes: PMatrix;
begin
  new(MRes);
  gluLoadmatrixIdentity(PgluMatrix(MRes));
  M1 := PMatrix(Matrix1);
  M2 := PMatrix(Matrix2);
  for x := 0 to 3 do begin
    for y := 0 to 3 do begin
      sum := 0;
      for i := 0 to 3 do begin
        sum := sum + M1^[i][y] * M2^[x][i];
      end;
      MRes^[x][y] := sum;
    end;
  end;
  for x := 0 to 3 do
    for y := 0 to 3 do
      M1^[x][y] := MRes^[x][y];
  dispose(MRes);
end;

Ich hab mal zum testen bei der OpenGL Matrix un bei meiner die gleichen Operationen durgeführt (Translate(0,0,-10) und Rotate(45, 1, 0, 0)) und mir anzeigen lassen. Es stimmen alle Werte, bis auf den Z-Wert der Z-Achse (mein Wert ist 0 und er sollte SQRT(2) sein). Ich weiß auch nich wo ich den Fehler suchen soll. Die RotationsMatrix hab ich so wie sie da steht von Wikipedia abgeschrieben. Wäre nett, wenn sich das ma jmd angucken könnte, der in der Schule bei Matricen aufgepasst hat :P

€: hab ne Andere Rotationsmatrix genommen (vom englischen Wiki) und mit gehts (Code ist angepasst). Jetzt hab ich aber noch n anderes Problem. Und zwar dreht sich die Matrix ja jetz immer um ihre eigenen Achsen, ich würde sie aber gern um die Norm-Achsen drehen (Norm-Achsen klingt iwie komisch, halt um die Achsen, die man direkt nach dem initialisieren der Matrix hat). Aber ich wei0 nich wie ich das anstellen soll...

MfG & Thx Bergmann

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 17, 2010 08:35 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Die RotationsMatrix hab ich so wie sie da steht von Wikipedia abgeschrieben.

Also da sollte an jeder Stelle der Matrix der Term (1-c) vorkommen für "1 - cos alpha". Bei dir aber irgendwie nicht ;)

Zitat:
Und zwar dreht sich die Matrix ja jetz immer um ihre eigenen Achsen, ich würde sie aber gern um die Norm-Achsen drehen

Mit deiner Methode kannst du doch eine beliebige Achse als Drehachse angeben, so auch (1,0,0), (0,1,0) und (0,0,1). Alternativ kannst du die Matrizen nehmen die in dem von dir verlinkten Artikel der Wikipedia für die X, Y und Z-Achse stehen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 17, 2010 08:48 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

Coolcat hat geschrieben:
Also da sollte an jeder Stelle der Matrix der Term (1-c) vorkommen für "1 - cos alpha". Bei dir aber irgendwie nicht ;)
steht doch oben drin?! siehe gluRotateMatrix...

Coolcat hat geschrieben:
Mit deiner Methode kannst du doch eine beliebige Achse als Drehachse angeben, so auch (1,0,0), (0,1,0) und (0,0,1). Alternativ kannst du die Matrizen nehmen die in dem von dir verlinkten Artikel der Wikipedia für die X, Y und Z-Achse stehen.
Die Achse die ich da angeb ist aber eine Achse in dem System der Matrix, ich will aber um die Achsen des WeltSystems drehen, und da weiß ich nich, wie ich die Achse berechnen soll, um die ich da drehen muss, oder ob es da einen komplett anderen Weg gibt.

MfG Bergmann

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 17, 2010 09:10 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
steht doch oben drin?! siehe gluRotateMatrix...

Öhm, nehmen wir das Element in der ersten Spalte, erste Zeile:
SQR(X) + (1-SQR(X))*c
Ich sehe da kein 1-c....mir ist auch ein Rätsel wie du da auf 1-x² kommst. Das sollte eigentlich X*X*(1-c) + c sein. Übrigens fördert es in diesem Fall die Leserlichkeit enorm wenn du nicht die SQR-Funktion benutzt sondern einfach X*X schreibst. Dann fällt dir nämlich auf das es immer "Achse*Achse*(1-c) + Irgendwas" ist.

Zitat:
Die Achse die ich da angeb ist aber eine Achse in dem System der Matrix, ich will aber um die Achsen des WeltSystems drehen, und da weiß ich nich, wie ich die Achse berechnen soll, um die ich da drehen muss, oder ob es da einen komplett anderen Weg gibt.

Wenn mich nicht alles täuscht brauchst du zuerst eine Matrix die ins Weltsystem zurückrechnet, nennen wir sie W und deine gewünschte Rotation nennen wir R. Deine Matrix ist: W^(-1)*R*W

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 17, 2010 09:21 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zusatz:
Wenn M deine aktuelle Matrix ist würde das ja so aussehen:
W^(-1)*R*W*M
wobei M = W^(-1)....es kommt also auf das gleiche hinaus als wenn du von der anderen Seite aus dran multiplizierst: M * R

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 17, 2010 10:06 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Tschuldigung, dass ich mich hier einmische. Ich wollte nur auf Folgendes aufmerksam machen:

Ich habe vor ziemlich genau einem Jahr eine Matrix für Shaddow gepostet, die mittels Winkel und Achse erzeugt werden kann. Diese Funktion gibt die gleichen Ergebnisse wie glRotate. Der Beitrag ist hier zu finden: http://www.delphigl.com/forum/viewtopic.php?f=3&t=8476&hilit=Kamera&start=15, runterscrollen bis zu meinem Beitrag vom Do Jun 25, 2009 13:55.

HINWEIS: gleich zu Beginn wird Sinus und Cosinus berechnet, und zwar getrennt voneinander. Man kann NICHT den Cosinus aus dem Sinus berechnen, denn man würde das Vorzeichen verlieren, leicht zu ersehen aus Cos = Wurzel(1-sin²). Klarerweise würde die Matrix in gewissen Fällen dann Rubbish erzeugen.

Noch ein HINWEIS: Die Funktion wird schneller, wenn man die Parameter als "Const" deklariert (ein Hinweis von Lossy, danke nochmal).

Und der letzte HINWEIS: Ich weiß, Du wirst jetzt die Augen verdrehen, aber ich empfehle Dir, nicht mit Matrizen zu arbeiten, sondern gleich Quaternionen zu nehmen. Zwar geht das zunächt wunderbar mit den Matrizen, aber es kommt der Tag, an dem man ansteht. Matrizen lassen sich nicht interpolieren. Oder Du beginnst zwar mit Matrizen, aber gestaltest Deine Lib so, dass Du später leicht umsteigen kannst. Quaternionen lassen sich genauso verwenden wie Matrizen mit dem zusätzlichen Vorteil, interpolierbar zu sein.

Viele Grüße,
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 17, 2010 11:13 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

@Coolcat: Jetzt stimmts, du hast aber noch n dreher drin. Bis jetzt war es M = M * R und jetzt ist es M = R * M. Dabei muss aber vorher an den Koordinatenursprung (bzw an den Fixpunkt der Drehung) verschoben werden un danach wieder zurück. Dankeschön :) Warum ich die Rotationsmatrix jetzt so komisch zusammensetz weiß ich auch nich genau, ich hab mir nach dem englischen Wiki gerichtet, weil mit der Matrix im deutsch Wiki hats nich funktioniert.
@Traude: Das was du in deinem Beitrag gepostet hast, hatte ich glaube auch so. Aber ich glaub bei mir war irgend ein dreher drin, oder die Quelle war falsch, weil es ja nich ging. Aber mit der Rotationsmatrix aus dem englischen Wiki gehts auch.
Hinweis 1: ich weiß, hab ich auch schon so gemacht :)
Hinweis 2: hatte ich auch schon ^^
Hinweis 3: Danke für den Tipp, aber ich werd es erstmal so lassen, weil ich keine Zeit hab um mich neu in das Thema einzuarbeiten, denn von Quaternionen höre ich heute zum 1. mal. Wenn die Zeit gekommen ist werd ich mir das aber mal angucken.

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 17:16 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

ich hab mir grad mal die Quaternionen angesehen. Und es überall nur die Rede von Drehungen. Eine Positionsbestimmung ist wo mit den nich möglich? Da müsste man ja Rotation und Position unabhängig voneinander Interpolieren. Gibts da vlt iwo n Tutorial oder sowas dazu?

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 18:03 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Nein, das wird immer gerne verschwiegen wie man die Dinger richtig benutzt. Also mit einem reinen Quaternion kannst du keine Translation machen. ABER, du kannst einfach einen Translations-Vektor dazu speichern.

Hier einfach mal Copy&Paste aus meinem Code. Die Methode rotate() eines Quaterions wendet das Quaternion einfach auf den Punkt an. Die Klasse Frame3 kannst du dann quasi genauso benutzen wie eine Matrix, mit dem Unterschied das du weniger Rechenoperationen benötigst und das ganze numerisch stabiler ist. Nur wenn du mehrere Punkte mit deinem Frame3 transformieren willst solltest du es erst in eine Matrix umwandeln. Ein Frame erlaubt aber nur Translation und Rotation. Eine Skalierung, Spiegelung, Scherung oder Projektion ist nicht möglich.

Code:
/***************************************************************************
 *   Copyright (C) 2010 by Martin Weusten                                  *
 *   martin dot weusten at rwth minus aachen dot de                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef INCLUDE_GUARD_CML_FRAME3
#define INCLUDE_GUARD_CML_FRAME3

/** A 'Frame' is a Quaternion4 combined with a Vector3.
 * Using this class you can use quaternions similar as 4x4 matrices. The
 * quaternion does represent the rotation part, the vector is the translation. */
template<class T> class Frame3
{
public:
   Frame3<T>() { } ///< no-initialization constructor
   Frame3<T>(const Vector3<T>& _p, const Quaternion4<T>& _q);
   
   // assignment operators
   Frame3<T>& operator*=(const Frame3<T>& f);    ///< combine two frames and assign result

   // binary operators
   Frame3<T> operator*(const Frame3<T>& f) const; ///< combine two frames
   
   // operations
   Matrix44<T> matrix() const;    ///< convert transformation into matrix
   Frame3<T> inverse() const;     ///< calculate inverse transformation
   Vector3<T> transform(const Vector3<T>& v) const;    ///< transform point
   bool isNaN() const;                 ///< tests if one of the values is NaN = 'Not a Number'
   
   Vector3<T> p;
   Quaternion4<T> q;
};


template<class T> inline Frame3<T>::Frame3(const Vector3<T>& _p, const Quaternion4<T>& _q)
   : p(_p), q(_q)
{
   
}

template<class T> inline Frame3<T>& Frame3<T>::operator*=(const Frame3<T>& f)
{
   p += q.rotate(f.p);
   q *= f.q;
   return *this;
}

template<class T> inline Frame3<T> Frame3<T>::operator*(const Frame3<T>& f) const
{
   return Frame3<T>(p + q.rotate(f.p), q * f.q);
}

template<class T> inline Matrix44<T> Frame3<T>::matrix() const
{
   return q.getMatrix44().setW(p);
}

template<class T> inline Frame3<T> Frame3<T>::inverse() const
{
   const Quaternion4<T>& c = q.conjugated();
   return Frame3<T>(c.rotate(-p), c);
}

template<class T> inline Vector3<T> Frame3<T>::transform(const Vector3<T>& v) const
{
   return p + q.rotate(v);
}

template<class T> inline bool Frame3<T>::isNaN() const
{
   return p.isNaN() || q.isNaN();
}

#endif

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 19:13 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Zitat:
Nein, das wird immer gerne verschwiegen wie man die Dinger richtig benutzt.
Dafür hasse ich die Mathematiker: sie hören einem gar nicht zu. Wenn man fragt: "Was sind Quaternionen?" dann verstehen sie immer: "Wie rechnet man mit Quaternionen?" Und sie erklären einem dann laaang und breiiiit wie man das macht. Was Quaternionen bewirken, steht dann meist im Kleingedruckten. :roll:

Wie Coolcat schon sagte, kann man damit rotieren und sonst nix. Aber das können sie besser als Matrizen, denn sie sind

a) kleiner (brauchen also weniger Speicherplatz, das war auf alten Grafikkarten ein Thema: wieviele Floats gehen in ein Uniform-Array? Und da gehen eben mehr Quaternionen als Matrizen in ein Uniform-Array, was den Effekt hat, dass man weniger Schwierigkeiten hat, Skelette mit vielen Gelenken zu berechnen, allerdings muss man immer den Positionsvektor noch zusätzlich berücksichtigen).

b) sind im Gegensatz zu Matrizen in der Lage, effektiv zu interpolieren (man kann mit relativ wenig Rechenaufwand zwischen zwei Quaternionen interpolieren, Stichwort: "Lerp" = Linear Interpolation; es gibt auch "Slerp" = Spherical Linear Interpolation und auch noch einige andere)

Ich hätt natürlich auch Sourcecode - sogar in Pascal - aber Du bist ja ein Self-Made-Man.


Zuletzt geändert von Traude am Do Jun 24, 2010 20:01, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 19:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,

Traude hat geschrieben:
Ich hätt natürlich auch Sourcecode - sogar in Pascal - aber Du bist ja ein Self-Made-Man.

meistens schon, aber wenn ich gar kein Ahnung hab guck ich mir auch gern mal Code von anderen an :) Wäre cool, wenn du mir den mal zukommen lassen könntest.

MfG Bergmann.

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 19:26 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Das ist mein SourceCode, denn kannst Du gerne haben; wie man mit Quaternionen rechnet, ist kein Geheimnis. Ich habe den Code nirgendwo abgeschrieben, sondern jedes einzelne nach dem mathemtischen Algo gebastelt und mit mindestens zwei (meistens C++) Implementierungen abgeglichen. Wenn ich es wichtig fand, habe ich die Quelle dazugeschrieben. Sollte also glaub ich unbedenklich sein, das zu verwenden. Solltest Du Fehler finden wäre ich natürlich dankbar für eine Rückmeldung. Übersetzt in eine Lizenz wäre das eine BSD-Lizenz.

Ich garantiere aber für nichts. Als Hinweis: Wenn ich die Dinger schon mal benutzt habe und es funktioniert hat, dann steht dabei: "Has been tested and found OK". Bei manchen steht das nicht dabei. Allerdings werden diese Funktionen manchmal von anderen Funktionen verwendet, wo der "OK" Vermerk dabei ist. Ich war also nicht immer ganz konsequent.

Auf Schnelligkeit optimiert ist der Code nicht, mehr auf *Deutlichkeit*. Aber das sollte ja ganz in Deinem Sinne sein.

Zwei wichtige Definitionen:
Code:
   TQuaternion = Packed Record RealW,ImagX,ImagY,ImagZ: TFloat32; End;
   TVector3F   = Packed Record X,Y,Z: TFloat32; End;

Meine Variablen sehen ein wenig anders aus als die Delphi-Variablen, aber sie sollten eigentlich selbsterklärend sein, siehe z.B. TFloat32. Die Funktion "Quaternion", also gleich die erste, hat noch ein Manko: man sollte sie normalisieren. Aber das ist in dem SourceCode derzeit noch nicht drin. Wenn man bei "AX,AY,AZ" eine nicht normalisierte Rotationsachse eingibt, ereignen sich seltsame Dinge.
Code:
//********************************************************************
//                        Q U A T E R N I O N
//********************************************************************
// Has been tested and found OK
Function Quaternion(Const Angle,AX,AY,AZ: TFloat32): TQuaternion;
Var
   LocalQuat: TQuaternion;
   LocalVector: TVector3F;
   CosHalfAngle,SinHalfAngle: TFloat32;
Begin
   CosHalfAngle:= Cos(Angle/2*PIDIV180);
   SinHalfAngle:= Sin(Angle/2*PIDIV180);

   With Result Do
   Begin
      RealW:= CosHalfAngle;
      ImagX:= AX*SinHalfAngle;
      ImagY:= AY*SinHalfAngle;
      ImagZ:= AZ*SinHalfAngle;
   End;
End;
//********************************************************************
// Has been tested and found OK
Function QuaternionAdd(Const Quat1,Quat2: TQuaternion): TQuaternion;
Begin
   With Result Do
   Begin
      RealW:= Quat1.RealW + Quat2.RealW;
      ImagX:= Quat1.ImagX + Quat2.ImagX;
      ImagY:= Quat1.ImagY + Quat2.ImagY;
      ImagZ:= Quat1.ImagZ + Quat2.ImagZ;
   End;
End;
//********************************************************************
// Linear interpolation between two quaternions (LERP)
// Has been tested and found OK
Function QuaternionBlendLinear(Const Quat1,Quat2: TQuaternion;
               Const AFactor: TFloat32): TQuaternion;
Begin
    Result:= QuaternionNormalize(QuaternionAdd(
         (QuaternionScale(Quat1,(1-AFactor))),
         (QuaternionScale(Quat2, AFactor))));
End;
//********************************************************************
// Spherical linear interpolation between two quaternions (SLERP)

//                      sin(1 - t)Alpha          sin(t)Alpha
// Slerp(q1, q2, t) :=  ---------------  * q1 +  -----------  * q2
//                         sin Alpha              sin Alpha

// where cos Alpha := q1 · q2

// Has been tested and found OK
Function QuaternionBlendSpheric(Quat1,Quat2: TQuaternion;
               Const AFactor: TFloat32): TQuaternion;
Var
   AlphaInRad,CosAlpha,SinAlpha,Scale0,Scale1: TFloat32;
Begin
   // Calculate angle between the two quaternions
   CosAlpha:= QuaternionDotProduct(Quat1,Quat2);
   AlphaInRad:= ArcCos(CosAlpha);
   SinAlpha:= Sin(AlphaInRad);

   // Consider negative cosinus (angles between 90 and 270 degree)
   If CosAlpha < 0
   Then Begin
      CosAlpha:= Abs(CosAlpha);
      Quat2:= QuaternionConjugate(Quat2);
   End;

   // Calculate spherical interpolation factors
   Scale0:= Sin((1-AFactor) * AlphaInRad) / SinAlpha;
   Scale1:= Sin(AFactor * AlphaInRad) / SinAlpha;

   With Result Do
   Begin
      RealW:= Scale0*Quat1.RealW + Scale1*Quat2.RealW;
      ImagX:= Scale0*Quat1.ImagX + Scale1*Quat2.ImagX;
      ImagY:= Scale0*Quat1.ImagY + Scale1*Quat2.ImagY;
      ImagZ:= Scale0*Quat1.ImagZ + Scale1*Quat2.ImagZ;
   End;
End;
//********************************************************************
// Has been tested and found OK
Function QuaternionConjugate(Const AQuat: TQuaternion): TQuaternion;
Begin
   With Result Do
   Begin
      ImagX:=-ImagX; ImagY:=-ImagY; ImagZ:=-ImagZ;
   End;
End;
//********************************************************************
// Has been tested and found OK
Function QuaternionDotProduct
               (Const Quat1,Quat2: TQuaternion): TFloat32;
Begin
   Result:= +Quat1.RealW * Quat2.RealW
            +Quat1.ImagX * Quat2.ImagX
            +Quat1.ImagY * Quat2.ImagY
            +Quat1.ImagZ * Quat2.ImagZ;
End;
//********************************************************************
Function QuaternionInverse(Const AQuat: TQuaternion): TQuaternion;
Begin
   Result:= QuaternionNormalize(QuaternionConjugate(AQuat));
End;
//********************************************************************
// Has been tested and found OK
Function QuaternionMultiply
               (Const ANormQuat1,ANormQuat2: TQuaternion): TQuaternion;
Begin
  With Result Do
  Begin
     RealW:= + ANormQuat1.RealW * ANormQuat2.RealW
             - ANormQuat1.ImagX * ANormQuat2.ImagX
             - ANormQuat1.ImagY * ANormQuat2.ImagY
             - ANormQuat1.ImagZ * ANormQuat2.ImagZ;

     ImagX:= + ANormQuat1.RealW * ANormQuat2.ImagX
             + ANormQuat1.ImagX * ANormQuat2.RealW
             + ANormQuat1.ImagY * ANormQuat2.ImagZ
             - ANormQuat1.ImagZ * ANormQuat2.ImagY;

     ImagY:= + ANormQuat1.RealW * ANormQuat2.ImagY
             - ANormQuat1.ImagX * ANormQuat2.ImagZ
             + ANormQuat1.ImagY * ANormQuat2.RealW
             + ANormQuat1.ImagZ * ANormQuat2.ImagX;

     ImagZ:= + ANormQuat1.RealW * ANormQuat2.ImagZ
             + ANormQuat1.ImagX * ANormQuat2.ImagY
             - ANormQuat1.ImagY * ANormQuat2.ImagX
             + ANormQuat1.ImagZ * ANormQuat2.RealW;
  End;
End;
//********************************************************************
Function QuaternionNormalize(Const AQuat: TQuaternion): TQuaternion;
Var QuatValue: TFloat32;
Begin
   QuatValue:= QuaternionValue(AQuat);
   If QuatValue <> 0
      Then With Result Do
      Begin
         RealW:= AQuat.RealW / QuatValue;
         ImagX:= AQuat.ImagX / QuatValue;
         ImagY:= AQuat.ImagY / QuatValue;
         ImagZ:= AQuat.ImagZ / QuatValue;
      End
      Else Result:= QUATIDENTITY;
End;
//********************************************************************
Function QuaternionScale(Const AQuat: TQuaternion;
               Const AFactor: TFloat32): TQuaternion;
Begin
   With Result Do
   Begin
      RealW:= AQuat.RealW * AFactor;
      ImagX:= AQuat.ImagX * AFactor;
      ImagY:= AQuat.ImagY * AFactor;
      ImagZ:= AQuat.ImagZ * AFactor;
   End;
End;
//********************************************************************
Function QuaternionValue(Const AQuat: TQuaternion): TFloat32;
Begin
   With AQuat Do
      Result:= RealW*RealW + ImagX*ImagX + ImagY*ImagY + ImagZ*ImagZ;
End;
//********************************************************************
//             Q U A T E R N I O N - Conversion
//********************************************************************
// Source: http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
Function AngleAxisToQuaternion
               (Const ARotation: TAngleAxis): TQuaternion;
Begin
   With ARotation,Axis Do Result:= Quaternion(Angle,X,Y,Z);
End;
//********************************************************************
// Source:http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
Function QuaternionToAngleAxis(Const AQuat: TQuaternion): TAngleAxis;
Var Scale: TFloat32;
Begin
   With AQuat Do Scale:= Sqrt(ImagX*ImagX+ImagY*ImagY+ImagZ*ImagZ);

   With Result Do If Scale <> 0
      Then Begin
         Angle:= 2*ArcCos(AQuat.RealW)/PIDIV180;
         Axis.X:= AQuat.ImagX/Scale;
         Axis.Y:= AQuat.ImagY/Scale;
         Axis.Z:= AQuat.ImagZ/Scale;
      End
      Else Begin
         Angle:= 0;
         Axis:= ZPLUSVECTOR;
      End;
End;
//********************************************************************
// Source: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
// Has been tested and found OK
Function QuaternionToMatrix(AQuat: TQuaternion): TMatrix4D;
Begin
   Result:= MATIDENTITY;

   AQuat:= QuaternionNormalize(AQuat);
   With AQuat Do Begin
      Result[0].X:= 1 - 2*ImagY*ImagY - 2*ImagZ*ImagZ;
      Result[0].Y:= 2*ImagX*ImagY + 2*RealW*ImagZ;
      Result[0].Z:= 2*ImagX*ImagZ - 2*RealW*ImagY;
      Result[0].W:= 0;

      Result[1].X:= 2*ImagX*ImagY - 2*RealW*ImagZ;
      Result[1].Y:= 1 - 2*ImagX*ImagX - 2*ImagZ*ImagZ;
      Result[1].Z:= 2*ImagY*ImagZ + 2*RealW*ImagX;
      Result[1].W:= 0;

      Result[2].X:= 2*ImagX*ImagZ + 2*RealW*ImagY;
      Result[2].Y:= 2*ImagY*ImagZ - 2*RealW*ImagX;
      Result[2].Z:= 1 - 2*ImagX*ImagX - 2*ImagY*ImagY;
      Result[2].W:= 0;
   End;
End;


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 20:09 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 11, 2009 08:02
Beiträge: 532
Programmiersprache: pascal (Delphi 7)
Zitat:
Wenn man fragt: "Was sind Quaternionen?" dann verstehen sie immer: "Wie rechnet man mit Quaternionen?"

ähm... die richtige Antwort auf "Was sind Quaternionen?" wäre doch eigentlich: "Zahlen, die aus einem realteil und drei imaginärteilen bestehen" :wink: (oder so ähnlich). Das ist (glaube ich) auch nicht viel aufschlussreicher.

sorry, aber das musste sein.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 20:51 
Offline
DGL Member
Benutzeravatar

Registriert: Di Apr 29, 2008 18:56
Beiträge: 1213
Programmiersprache: Delphi/FPC
SUPER! Dankeschön, ich gucks mir ma an un versuch es auch zu verstehen^^ Wenn ich Fagen hab oder so, dann meld ich mich nochma...

MfG & Thx Bergmann

_________________
Aktuelle Projekte: BumpMapGenerator, Massive Universe Online
Auf meiner Homepage gibt auch noch paar Projekte und Infos von mir.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Matrixrotation
BeitragVerfasst: Do Jun 24, 2010 21:06 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hey, gern geschehen. Ich hoffe, es hilft. :wink:


sharkman hat geschrieben:
ähm... die richtige Antwort auf "Was sind Quaternionen?" wäre doch eigentlich: "Zahlen, die aus einem realteil und drei imaginärteilen bestehen"
Ich mache mir Sorgen. Du bist ein schwerer Fall. Ganz offensichtlich indoktriniert von irgendwelchen Mathematik-Lehrern. 8)


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 16 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Mathematik-Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.025s | 17 Queries | GZIP : On ]