Matrizenproblem
Übersicht

![]() |
NoobodyBetreff: Matrizenproblem |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hier mal ein kleines Problem für die Mathecracks unter euch:
Da die TFormPoint/Vector/Normal - Funktionen aus B3D unheimlich nützlich sind, versuche ich seit einiger Zeit, sie in einer anderen Sprache nachzubauen. Ähnlich wie in B3D habe ich Entities, die per Move/Position/Turn/Rotate - Methoden bewegt werden können. Intern wird für jedes Entity eine Transformationsmatrix und ihre Inverse gespeichert, um damit weiterrechnen zu können. Die TFormBefehle sind mit Matrizen dann relativ einfach - einfach den Punkt/Vektor mit der Matrix multiplizieren und schon ist er in einem anderen Koordinatenraum. So zumindest in der Theorie, in der Praxis bringe ich aber nur den TFormPoint-Befehl zustande. Mit Vektoren bekomme ich nur falsche Resultate, allerdings verstehe ich einfach nicht, warum. Die Transformationsmatrize für ein Entity setze ich folgendermassen zusammen Code: [AUSKLAPPEN] Transformation = Translation( TX, TY, TZ )*RotationZ( RotZ )*RotationX( RotX )*RotationY( RotY )*Skalierung( SX, SY, SZ )
Die Inverse einfach andersrum Code: [AUSKLAPPEN] InverseTransformation = Skalierung( 1/SX, 1/SY, 1/SZ )*RotationY( -RotY )*RotationX( -RotX )*RotationZ( -RotZ )*Translation( -TX, -TY, -TZ )
Die Funktionen Skalierung(), Translation() etc. liefern Matrizen zurück und der * - Operator ist entsprechend für Matrizen überladen worden. Für Vektoren muss dann selbstverständlich der Translationsteil weggelassen werden, da Vektoren keine Position haben (fiel mir auch relativ spät auf ![]() Die TFormPoint - Funktion sähe, übertragen auf BB (mal abgesehen vom *, das in BB natürlich nicht geht), dann ungefähr so aus BlitzBasic: [AUSKLAPPEN] ]Function TransformPoint.TVector( V.TVector, Source.TEntity, Dest.TEntity ) Für Vektoren wird eine beinahe identische Funktion benutzt, die nur eine andere Transformationsmatrix wählt (die ohne Translation). Ich habe den Code dutzende Male durchgesehen, ob ich nicht irgendwo einen sehr dummen Fehler mache, aber ich habe nichts gefunden. Daher ist meine Frage: Übersehe ich etwas, das bei Vektortransformation anders ist wie bei der Transformation eines Punktes, von der Translation mal abgesehen? Soweit ich Matrizen und Vektoren verstehe, müsste ich alles richtig machen, aber ich kann auch eine Wissenslücke haben. Ein Fehler in den Matrizenfunktionen kann ich mehr oder weniger ausschliessen, da Punkte ja korrekt transformiert werden. Falls erwünscht, kann ich die betroffenen Teile des Codes hochladen (C++). |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
Arrangemonk |
![]() Antworten mit Zitat ![]() |
---|---|---|
geht nicht einfach 2 punkte auf dem vektor nehmendie richtung und länge darstellen, dann die punkte drehen und mit denen den neuen vektor machen? | ||
ingeneur |
![]() |
NiborBetreff: Re: Matrizenproblem |
![]() Antworten mit Zitat ![]() |
---|---|---|
Noobody hat Folgendes geschrieben: BlitzBasic: [AUSKLAPPEN]
]Function TransformPoint.TVector( V.TVector, Source.TEntity, Dest.TEntity ) Sollte nicht Source\InverseTransformation anstatt Source\Transformation verwendet werden um den Punkt in diesem Koordinatensystem ersteinmal global zu machen und dann in das neue übertragen werden? Abgesehen von der erwähnten vernachlässigung der Translation bei Vektoren gibt es meines Wissens keine Unterschiede zw. Punkte und Vektoren. |
||
http://www.blitzforum.de/showcase/203/ |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hatte das nicht zufällig was mit Quaternionenzu tun?
(Womit sich mein mathematisches Wissen zum Thema auch erschöpft... ![]() |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
arrangemonk hat Folgendes geschrieben: geht nicht einfach 2 punkte auf dem vektor nehmendie richtung und länge darstellen, dann die punkte drehen und mit denen den neuen vektor machen?
Das wäre für Vektoren in der Tat möglich, allerdings nicht sehr effizient, da ich die Matrizen in einem Raytracer benötige, der Vektorentransformationen einige dutzend Millionen Mal pro Frame berechnet ![]() Nibor hat Folgendes geschrieben: Sollte nicht Source\InverseTransformation anstatt Source\Transformation verwendet werden um den Punkt in diesem Koordinatensystem ersteinmal global zu machen und dann in das neue übertragen werden? Sehr gut beobachtet. Da ich den Code nur mit Schulwissen über Matrizen schrieb, habe ich die Transformation aus eigener Logik umgekehrt definiert, wie es heute in 3D-Grafik üblich ist. Von 'aussen' (global) nach 'innen' (lokal) war für mich quasi 'vorwärts', daher die Transformation; 'rückwärts' wäre es dann die Inverse. Daher verwende ich die richtige Matrix, aber den falschen Namen. Xeres hat Folgendes geschrieben: Hatte das nicht zufällig was mit Quaternionen zu tun?
Nur bedingt, da Quaternionen nur bei Rotationen zum Zug kommen und nicht bei ganzen Transformationen. Ich habe aber heute morgen das Problem gelöst. Schlussendlich habe ich einen Teil des Codes frisch geschrieben und solange angepasst, bis ich die gleichen Resultate wie in B3D mit den TForm-Befehlen erhalten habe. Es stellte sich dann heraus, dass es einen fundamentalen Unterschied zwischen Vektoren und Normalen bei der Transformation gibt. Vom lokalen in den globalen Raum wird bei Vektoren die Matrix Rotation*Skalierung verwendet, bei Normalen aber Rotation*InverseSkalierung. Da ich meistens mit Normalen arbeitete, diese aber als Vektoren transformierte, bekam ich nur falsche Resultate und ich verdächtigte einen grundlegenden Fehler in der verwendeten Matrix. Beim Schreiben des Codes ging ich vorher davon aus, dass die Transformation von Vektoren und Normalen gleich abläuft, nur dass bei den Normalen nach der Transformation einfach noch eine Normalisation ausgeführt wird. Dem ist aber nicht so. Der Richtungsvektor eines Sichtstrahls beispielsweise, der ja meistens auch die Länge eins hat, wird normal mit der Vektorentransformation behandelt und dann normalisiert. Eine Oberflächennormale aber wird mit der Normalentransformation (die mit der inversen Skalierung) in andere Koordinatensysteme gezogen und dann normalisiert. Zwischen Vektoren, die einfach die Länge 1 besitzen, und Normalen, die direkt mit einer Oberfläche zu tun haben, scheint also ein grosser Unterschied zu bestehen. Dank Blitz3D weiss ich das nun ![]() Den Raytracercode habe ich angepasst und er scheint nun perfekt zu laufen. Danke für eure Hilfe! |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group