Transformationen

Werbung
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Seminar
Grafikprogrammierung mittels Java3D
Inhaltsverzeichnis
Allgemeines zu geometrische Transformationen ..................Seite 2
Translation ...........................................................................Seite 3
Skalierung ............................................................................Seite 5
Rotation ...............................................................................Seite 6
TransformGroup ...................................................................Seite 9
Kombination von Transformationen......................................Seite 10
Quellen ................................................................................Seite 14
Anhang:
Szenengraphen RoboterArm................................................Seite 15
Quell-Coder RoboterArm.java ..............................................Seite 16
Quell-Code AxenColorCubeInter.java ..................................Seite 25
1
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Allgemeines zu geometrische Transformationen
Mit der Ausarbeitung über Transformationen im Seminar Java3D werden die
wichtigsten geometrischen Transformationen dreidimensionaler Objekte betrachtet.
Außerdem wird gezeigt wie man die Transformationen auf Objekte in Java3D
anwenden kann. Java3D speichert die dreidimensionalen Objekte anhand ihrer
Flächen. Zur Erklärung der Transformationen ist es aber einfacher sich die Flächen
als eine Anzahl von Punkten (Vertices) und eine Liste von Kanten vorzustellen. Die
Endpunkte der Kanten bestehen aus den Eckpunkten des Objekts. Durch die
geometrischen Transformationen wie Rotation, Skalierung und Translation auf die
Punkte eines Objekts, wird dieses in ein neues Koordinatensystem abgebildet. Die
Liste der Punkte eines Objekts ist durch V = { vi | vi = (xi, yi, zi)  R3 , i  N } definiert.
Damit man in Java mit diesen Raumpunkten in Form von Vektoren und Matrizen
rechnen kann, werden in dem Paket javax.vecmath die benötigten Klassen für
Vektoren und Matrizen bereitgestellt. Dieses Paket behandelt natürlich auch die
nötigen Funktionen, damit man mit diesen Vektoren und Matrizen rechnen kann. In
diesen Klassen gilt eine Namenskonvention die darauf hinweist zu welchem
Wertebereich die Inhalte zählen. Die Klassennamen enden alle auf einen
Kleinbuchstaben, der den Wertetyp der Komponente zeigt. So steht
-
b für byte
f für float und
d für double
Die Zahl, die vor diesen Buchstaben steht, deutet auf die Anzahl der
Wertkomponenten
hin.
Ein
dreidimensionaler
Vektor
mit
doppelter
Fließkommagenauigkeit wird in einer Instanz von Vector3d gespeichert. Die
vierdimensionale Matrize (4 x 4) mit einfach genauen Fließkommawerten ist eine
Instanz von Matrix4f.
Die
Transformationen
in
Java3D
werden
in
Objekten
des
Typs
javax.media.j3d.Transform3D
gespeichert.
Die
Objekte
wiederum
referenzieren
Instanzen
der
Klasse
javax.vecmath.Matrix4d.
Die
Transform3D-Klasse repräsentiert also eine 3D-transformationsmatrix in der
Form 4 x 4 für Verschiebungen, Drehungen und Dehnungen/Stauchungen.
Transform3D wird nicht direkt in einem Szenengraphen, sondern meistens in
Verbindung mit der TransformGroup-Klasse verwendet. Ein TransformGroup-Objekt
wird meistens aus der Kombination mehrer Transform3D-Objekten konstruiert.
2
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Translation
Die Translation ist eine Verschiebung der Punkte eines Objekts. Alle Punkte werden
dabei um tx in x-Richtung, ty in y-Richtung und tz in z-Richtung verschoben. Die
tx 
 
Translation ist eine Addition der Punkte um den Vektor  t y  .
 
tz 
 x   t x   x  t x   x' 
  
    
 y  +  t y  =  y  t y  =  y'
 z   t   z  t   z' 
   z 
 
z 
Um die die Transformation mit einer Matrixmultiplikation durchführen zu können, bei
der sich alle Punkte ändern, benötigt man eine Matrix, die um eine Dimension
erweitert ist. Die erweiterte Matrix hat in der unteren Zeile die Koordinaten (0 0 0 1),
so dass alle Punkte aus dieser Ebene wieder in die vierte Ebene abgebildet werden.
Auch die Punkte des Objekts müssen um eine Dimension erweitert und in
x
homogenen Koordinaten
y
dargestellt werden.
z
1
Mit dieser Vorgehensweise erhält man die folgende Translationsmatrix:
1

0
0

0

0 tx 

0 ty 
1 tz 

0 1 
0
1
0
0
Wird der Punkt nun mit dieser Translationsmatrix multipliziert, so erhält man das
gleich Ergebnis wie bei der Addition mit dem Translationsvektor.
1

0
0

0

0
1
0
0
0 tx 
 x   x  tx 


  
0 ty 
 y  y  ty 
O  =

1 tz 
z
z  tz 

  
1  1

0 1 
  

3
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Die zusätzliche Komponente beim Ergebnis wird nicht beachtet und weggelassen. In
Java3D erzeugt man diese 4 x 4 Matrix mit einem Transform3D-Objekt.
Transform3D translation = new Transform3D ();
Mit dem Standardkonstruktor erhält man so eine 4 x 4 Matrix, die mit der
1 0 0 0


0 1 0 0
Identitätsmatrix vorinstalliert ist. 
Damit diese Matrix die gewünschte
0 0 1 0


0 0 0 1


Transformation in Form einer Translation vornimmt, muss sie mit einer Funktion
initialisiert werden. Die Translation mit den Werten x, y, z mit einfacher
Fließkommagenauigkeit wird durch die Initialisierung des Matrix4d-Objekts mit der
Funktion Transform3D.setTranslation ( vector3f ) erreicht. Bei dieser
Funktion werden nur die Werte, die für die Translation notwendig sind, durch die
Werte in dem Vektor ausgetauscht.
translation.setTranslation ( new Vector3f ( x, y, z));
Die Funktion Transform3D.set(Vector3f) ändert die 4 x 4 Matrix in eine
Translationsmatrix, bei der alle anderen Werte zu der Identitätsmatrix gehören.
Transform3D.set(new Vector3f (x, y, z));)
Natürlich gibt es diese Translationsfunktionen auch mit Vektoren die eine doppelte
Fließkommagenauigkeit (Vector3d) haben.
4
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Skalierung
Die Skalierung eines Objekts wird auch als Dehnung bzw. Stauchung bezeichnet.
Bei der Skalierung eines Objekts wird jeder Punkt um den Faktor  x für die xKoordinaten,  y für die y-Koordinaten und  z für die z-Funktionen vergrößert bzw.
verkleinert.
Auch hier wird eine 4 x 4 Matrix verwendet, um durch Multiplikation mit den einzelnen
Ursprungspunkten in homogenen Koordinaten die neuen Zielpunkte zu erreichen.
 x

0
0

0

0
y
0
0
0
0
z
0
0
 x   x * x 


  
0
 y  y * y 
O  =

0
z
z * z 

  
1   1

1 
  

Die Transformationsmatrix wird hier auch wieder durch eine Transform3D-Instanz
bereitgestellt.
Transform3D scale = new Transform3D ();
Diese Identitätsmatrix muss nun durch eine entsprechende Funktion noch mit den
Skalierungswerten initialisiert werden.
Sind in der Matrix schon Skalierungsfaktoren vorhanden, so werden diese zuerst
herausgerechnet, bevor die neuen Skalierungswerte eingesetzt werden. Bei der
ersten der folgenden Funktionen werden verschiedene Werte für die x, y, z-Achse
benutzt und bei der zweiten Funktion erfolgt die Skalierung über alle drei Achsen
parallel.
scale.setScale ( new Vector3f ( x, y, z ));
scale.setScale (double scale);
Es gibt auch Funktionen, die in einem Schritt eine Skalierung und eine Translation in
eine Matrix einbinden.
set(Vector3f translation, float scale)
set(Vector3d translation, double scale)
5
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Rotation
Unter Rotation versteht man die Drehung um eine Achse. Bei den Rotationen gibt es
unterschiedliche Transformationsmatrizen für die Drehung um die x, y und z-Achse.
Bei der Rotation eines Objekts um die x-Achse bleiben die x-Koordinaten der Punkte
konstant und nur die y und z-Koordinaten verändern sich. Die Rotationen erfolgen
auch durch die Multiplikation einer 4 x 4 Matrix, der Rotationsmatrix, mit den
einzelnen Ursprungspunkten in homogenen Koordinaten. Die Rotationsmatrix wird
wieder durch ein Transform3D-Objekt bereitgestellt.
Transform3D rotation = new Transform3D ();
0
1

 0 cos 
Rx(  )  p = 
0 sin 

0
0

0
 sin 
cos 
0
0
x x


  

0
 y   y * cos   z * sin  
O  =
0
z
y * sin   z * cos  

  

 1  1

1 
  

Bei der Drehung um die y-Achse ist eine anders aufgebaute Transformationsmatrix
nötig, bei der die y-Koordinaten der Punkte konstant belieben.
 cos 

 0
Ry(  )  p = 
 sin 

 0

0 sin 
1
0
0 cos 
0
0
0
 x   x * cos   z * sin  

  

0
 y  y

O   =

0
z
 x * sin   z * cos  

  

 1  1

1 
  

Und schließlich gibt es noch eine Transformationsmatrix für die Drehung um die ZAchse, bei der die Z-Koordinaten der Punkte konstant bleiben.
 cos 

 sin 
Rz(  )  p = 
0

 0

 sin 
cos 
0
0
0
0
1
0
0
 x   x * cos   y * sin  

  

0
 y   x * sin   y * cos  
O  =

0
z
z

  

 1  1

1 
  

In Java3D werden diese Rotationsmatrizen einfach mit Hilfe der Transform3D-Klasse
und den dazugehörigen Funktionen erstellt.
6
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Rotation um die x-Achse:
rotation.rotX ( alpha );
Rotation um die y-Achse:
rotation.rotY ( alpha );
Rotation um die z-Achse:
rotation.rotZ ( alpha );
Der Winkel alpha gibt an um wie viel Grad das Objekt gedreht wird. Der Winkel wird
im Bogenmaß angegeben. Man kann aber auch ein Gradmaß einsetzen, und dieses
mit einer Funktion ins Bogenmaß umrechnen. Bei der Angabe im Bogenmaß
verwendet man die Konstante Math.PI und bei der Angabe in Gradmaß wird die
Funktion Math.toRadians benutzt.
1 34 
315
3
2


270
1 4
225
2
360 

4
45

Bogenmaß
Gradmaß
2
90
3
4

180 
7

135
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Neben den Standardfunktionen, bei denen man ein Objekt um die x, y oder z-Achse
dreht, gibt es aber noch Hilfsfunktionen in der Klasse Transform3D, mit denen man
eine Rotationsmatrix um eine beliebige Achse erstellen kann. Die Funktion
Transform3D.setRotation (AxisAngle4d) ermöglicht es die Raumachse
durch einen Vektor und einen Drehwinkel für die Rotation anzugeben. Das Objekt,
das den Vektor und den Winkel aufnimmt, ist ein AxisAngle4d-Objekt. Die Funktion
Transform3D.setRotation (AxisAngle 4d) passt die Rotationskomponente
an und behält Skalierungs- und Translationskomponenten bei.
Eine Transformationsmatrix, die ein Objekt 30
dreht, wird folgendermaßen aufgebaut.
0
um die erste Quadrantenhalbierende
Transform3D rotation = new Transform3D ();
transform.setRotation ( new AxisAngle4d ( 1, 1, 1,
Math.toRadians ( 30.0d)));
8
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
TransformGroup
Damit die oben gezeigten Transformationen auf ein Objekt angewendet werden
können, müssen sie durch ein TransformGroup-Objekt referenziert werden. Die
TransformGroup-Klasse ist von Group abgeleitet und wird zur Konstruktion des
Szenengraphen verwendet. Ein Objekt dieser Klasse spezifiziert geometrische
3D-Transformationen, die auf ein oder mehrere Subknoten angewendet werden
können. Die Transformationsmatrix wird auf eine der oben beschriebenen Weise
konstruiert.
Der Standardkonstruktor der TransformGroup-Klasse
TransformGroup transGroup = new TransformGroup ();
erstell ein TransformGroup-Objekt und initialisiert es mit der Identitätstransformationsmatrix.
Wird im Konstruktor schon eine Transformation in Form eines Transform3D-Objekts
angegeben, so wird das TransformGroup-Objekt direkt mit der Transformation
initialisiert.
TransformGroup transGroup =
new TransformGroup (Transform3D transformation);
Eine
Transformation
kann
man
auch
TransformGroup.setTransform angeben.
noch
nachträglich
mit
transGroup.setTransform ( Transform3D t1);
Wenn das TransformGroup-Objekt das erste Objekt unterhalb eines Locale ist, wirkt
die Transformation relativ zu diesen Koordinaten. Sind zwischen dem Locale und
dem TransformGroup-Objekt schon mehrere TransformGroup-Objekte, werden die
entsprechenden Transformationen vom Locale abwärts an kombiniert. Das durch
das TransformGroup-Objekt beschriebene Koordinatensystem ist dann relativ zum
Koordinatensystem der Vorgänger-TransformGroups. Man spricht in diesem Fall von
einer CM Transformation (Composite Modell).
Transform3D transform1 = new Transform3D ();
transform1.rotX (Math.PI/4.0d);
Transform3D transform2 = new Transform3D ();
transform2.rotY (Math.PI/6.0d);
TransformGroup transformgroup1 = new TransformGroup (transform1);
TransformGroup transformgroup2 = new TransformGroup (transform2);
transformgroup1.addChild (transformgroup2);
transformgroup2.addChild (new ColorCube (0.5));
9
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Kombination von Transformationen
Die Transform3D-Klasse stellt neben den Funktionen zur Konstruktion von
Transformationen auch Funktionen zur Kombination von Matrizen zur Verfügung.
Hierbei ist zu bemerken, dass Matrizenmultiplikationen assoziativ, aber nicht
kommutativ sind.
assoziativ
M1 * ( M2 * M3 ) = ( M1 * M2 ) * M3
nicht kommutativ
M1 * M2 * M3  M3 * M2 * M1
Die Transform3D-Klasse bietet aber nicht nur die Matrizenmultiplikation an, sondern
stellt auch Funktionen zur Verfügung, die zusammengefasste Transformationen ohne
Matrixmultiplikation erzeugen.
Transform3D.scaleAdd (double s, Transform3D trans);
Diese Funktion skaliert die eigene 4 x 4 Matrix mit s und addiert die
Transformationsmatrix des Transform3D-Objekts. ( this = s * this + trans )
Es gibt verschiedene Kombinationsfunktionen, die man alle in der Dokumentation
unter der Klasse Transform3D nachschauen kann. Wenn man keine Funktion findet,
die die gewünschte Transformation erzeugt, muss man die Matrizen direkt
miteinander multiplizieren. Dies geschieht mit der mul-Funktion. Diese kann zwei
Matrizen miteinander multiplizieren und in eine dritte schreiben
C=A  B
oder man multipliziert eine Matrix direkt in die Ausgangsmatrix.
A = A B
Transform3D a = new Transform3D ();
Transform3D b = new Transform3D ();
Transform3D c = new Transform3D ();
c.mul ( a, b )
a.mul ( b )
10
c  a  b
a  a  b
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Nach
diesen
beiden
Matrixmultiplikationen
Transformationsmatrizen a und c die gleiche Matrix.
steht
in
den
beiden
Transform3D rotate_a = new Transform3D();
Transform3D rotate_b = new Transform3D();
rotate_a.rotX(Math.PI/4.0d);
rotate_b.rotY(Math.PI/4.0d);
Y
Y
X
X
Z
Z
rotate_a.mul(rotate_b);
rotate_b.mul(rotate_a);
Y
Y
X
Z
X
Z
11
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Anstatt die einzelnen Transformationen zu kombinieren, ist es auch möglich für jede
Transformation ein TransformGroup-Objekt zu erstellen und diese übereinander im
Szenegraphen anzuordnen. Die TransformGroup-Objekte müssen nicht unbedingt
eine Geometrie referenzieren.
BG
View branch
graph
TG
TG
ColorCube
12
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Bei allen Rotationen, die bis jetzt vorgestellt wurden, sind die Drehungen nur um eine
Achse im Ursprung erfolgt. Soll die Drehung nun aber nicht um eine dieser Achsen
sondern um eine Achse im einem anderen Punkt, der im Koordinatensystem liegt,
durchgeführt werden, so muss man eine Kombination von Transformationen
durchführen.
Damit das Objekt um eine Achse im Punkt xr yr zr  rotiert, muss es zuerst mit
einer Translation  xr  yr  zr  in den Ursprung verschoben werden. Im
Ursprung kann man das Objekt nun um den gewünschten Winkel  drehen, und
zum Schluss muss das Objekt wieder mit einer Rücktranslation xr yr zr  zum
Ausgangspunkt verschoben werden.
Bei der Kombination dieser Vielzahl von Transformationen ist zu beachten, dass die
Matrixmultiplikation nicht kommutativ ist. Die Aktion die als erstes ausgeführt werden
soll, muss deshalb am weitesten rechts in der Matrizenmultiplikation stehen.
 1 0 0  xr 


R xr yr zr /   = T2 * R   * T1
 0 1 0  yr 
T1 
0 0 1  zr 


0 0 0

1


xr
 cos 

 sin 
Rz 
0

 0

 sin 
cos 
0
0
0
0
1
0
yr
zr 
0

0
0

1 
1

0
T2 
0

0

0
1
0
0
0
0
1
0
xr 

yr 
zr 

1 
xr
13
yr
zr 
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Quellen
Sun Java 3D Tutorial
http://developer.java.sun.com/developer/onlineTraining/java3d/
Skript Graphische Datenverarbeitung
Prof. Dr. Werner Heinzel
14
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Szenengraphen RoboterArm
Locale
View branch
graph
BG
objRoot
Behavior_Oberarm
TG
tg_oben
Behavior_Untererarm
TG
tg_schulter
TG
tg_oberArm
Shape3D
schulter
Appearance
Geometry
TG
tg_unten
Shape3D
oberArm
Appearance
Geometry
TG
tg_elle
Shape3D
elle
TG
tg_unterArm
Shape3D
unterArm
Appearance
Appearance
Geometry
15
TG
tg_hand
Shape3D
hand
Geometry
Appearance
Geometry
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Quell-Code RoboterArm.java
/* Name: RoboterArm
*
* Autor: Frank Krack
* Datum: 20. Oktober 2002
*
* Darstellung eines Roboterarms, der durch Tastendruck bewegt
* werden kann.
*
* - s --> ganzer Arm bewegt sich vorwärts
* - d --> ganzer Arm bewegt sich rückwärts
* - e --> Unterarm bewegt sich vowärts
* - r --> Unterarm bewegt sich rückwärts
*
*/
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.event.*;
import java.util.Enumeration;
//
RoboterArm erstellt einen Arm bei dem
//
Ober- und Unterarm durch Tastendruck bewegt werden können
public class RoboterArm extends Applet
{
public class Behavior_Oberarm extends Behavior
16
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
{
private TransformGroup targetTG;
private Transform3D rotation = new Transform3D();
private double angle_o = 0.0;
private WakeupOnAWTEvent lauscher =
new WakeupOnAWTEvent (KeyEvent.KEY_PRESSED);
// erstellt Behavior_Oberarm
Behavior_Oberarm(TransformGroup targetTG)
{
this.targetTG = targetTG;
}
// Initialisierung behavior
public void initialize()
{
// Erignis zum Abarbeitungsbeginn
this.wakeupOn(lauscher);
}
// diese Funktion wird von Java3D bei Eintritt
// des Erignis aufgerufen
public void processStimulus(Enumeration criteria)
{
TransformGroup tg_temp = new TransformGroup();
TransformGroup tg_punkt = new TransformGroup();
Transform3D t3d_punkt = new Transform3D();
Transform3D t3d_temp = new Transform3D();
KeyEvent key = (KeyEvent) lauscher.getAWTEvent()[0];
char c = key.getKeyChar();
switch (c)
{
case 's': // ganzer Arm vorwärts drehen
angle_o -= 0.1;
17
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
rotation.rotZ(angle_o);
targetTG.setTransform(rotation);
break;
case 'd': // ganzer Arm rückwärts drehen
angle_o += 0.1;
rotation.rotZ(angle_o);
targetTG.setTransform(rotation);
break;
}
this.wakeupOn (lauscher);
}
} // Ende der Klasse Behavior_Oberarm
public class Behavior_Unterarm extends Behavior
{
private TransformGroup targetTG;
private Transform3D rotation = new Transform3D();
private double angle_o = 0.0;
private double angle_u = 0.0;
private WakeupOnAWTEvent lauscher =
new WakeupOnAWTEvent (KeyEvent.KEY_PRESSED);
// erstellt Behavior_Unterarm
Behavior_Unterarm(TransformGroup targetTG)
{
this.targetTG = targetTG;
}
// Initialisierung behavior
public void initialize()
18
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
{
// Erignis zum Abarbeitungsbeginn
this.wakeupOn(lauscher);
}
// diese Funktion wird von Java3D bei Eintritt
// des Erignis aufgerufen
public void processStimulus(Enumeration criteria)
{
TransformGroup tg_temp = new TransformGroup();
TransformGroup tg_punkt = new TransformGroup();
Transform3D t3d_punkt = new Transform3D();
Transform3D t3d_temp = new Transform3D();
KeyEvent key = (KeyEvent) lauscher.getAWTEvent()[0];
char c = key.getKeyChar();
switch (c)
{
case 'e': // Unterarm vorwärts drehen
angle_u -= 0.1;
rotation.rotZ(angle_u);
// Stellungsmatrix des Unterams
// herausfinden
tg_temp =
(TransformGroup)targetTG.getChild(0);
tg_temp.getTransform(t3d_punkt);
t3d_temp.invert(t3d_punkt);
rotation.mul(t3d_temp);
t3d_punkt.mul(rotation);
targetTG.setTransform(t3d_punkt);
break;
case 'r': // Unterarm rückwärts drehen
19
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
angle_u += 0.1;
rotation.rotZ(angle_u);
// Stellungsmatrix des Unterams
// herausfinden
tg_temp =
(TransformGroup)targetTG.getChild(0);
tg_temp.getTransform(t3d_punkt);
t3d_temp.invert(t3d_punkt);
rotation.mul(t3d_temp);
t3d_punkt.mul(rotation);
targetTG.setTransform(t3d_punkt);
break;
}
this.wakeupOn (lauscher);
}
} // Ende der Klasse Behavior_Unterarm
public BranchGroup createSceneGraph()
{
// Wurzel des Szenengraphs
BranchGroup objRoot = new BranchGroup();
TransformGroup tg_oben = new TransformGroup();
tg_oben.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg_oben.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
tg_oben.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
TransformGroup tg_unten = new TransformGroup();
tg_unten.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
tg_unten.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
tg_unten.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
20
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
objRoot.addChild(tg_oben);
Transform3D t3d_schulter = new Transform3D();
t3d_schulter.set (new Vector3f(0.0f, 0.0f, 0.0f));
TransformGroup tg_schulter = new TransformGroup(t3d_schulter);
Appearance app_schulter = new Appearance();
ColoringAttributes col_schulter =
new ColoringAttributes (1.0f, 0.0f, 0.0f, 0);
app_schulter.setColoringAttributes (col_schulter);
Sphere schulter = new Sphere (0.1f, app_schulter);
tg_schulter.addChild(schulter);
Transform3D t3d_oberArm = new Transform3D();
t3d_oberArm.set (new Vector3f(0.0f, -0.35f, 0.0f));
TransformGroup tg_oberArm = new TransformGroup(t3d_oberArm);
Appearance app_oberArm = new Appearance();
ColoringAttributes col_oberArm =
new ColoringAttributes (0.0f, 0.0f, 1.0f, 0);
app_oberArm.setColoringAttributes (col_oberArm);
Cylinder oberArm = new Cylinder (0.1f, 0.5f, app_oberArm);
tg_oberArm.addChild (oberArm);
Transform3D t3d_elle = new Transform3D();
t3d_elle.set (new Vector3f(0.0f, -0.7f, 0.0f));
TransformGroup tg_elle = new TransformGroup(t3d_elle);
tg_elle.setCapability(TransformGroup.ALLOW_CHILDREN_READ);
tg_elle.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
Appearance app_elle = new Appearance();
ColoringAttributes col_elle =
new ColoringAttributes (0.0f, 1.0f, 0.0f, 0);
app_elle.setColoringAttributes (col_elle);
Sphere elle = new Sphere (0.1f, app_elle);
elle.setCapability(Sphere.ENABLE_GEOMETRY_PICKING);
tg_elle.addChild(elle);
Transform3D t3d_unterArm = new Transform3D();
t3d_unterArm.rotZ (Math.PI * 1.5f);
21
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
t3d_unterArm.setTranslation(new Vector3f(-0.32f, -0.7f, 0.0f));
TransformGroup tg_unterArm = new TransformGroup(t3d_unterArm);
Appearance app_unterArm = new Appearance();
ColoringAttributes col_unterArm =
new ColoringAttributes (0.5f, 0.5f, 1.0f, 0);
app_unterArm.setColoringAttributes (col_unterArm);
Cylinder unterArm = new Cylinder (0.085f, 0.44f, app_unterArm);
tg_unterArm.addChild (unterArm);
Transform3D t3d_hand = new Transform3D();
t3d_hand.set (new Vector3f(-0.6f, -0.7f, 0.0f));
TransformGroup tg_hand = new TransformGroup(t3d_hand);
Appearance app_hand = new Appearance();
ColoringAttributes col_hand =
new ColoringAttributes (1.0f, 1.0f, 0.0f, 0);
app_hand.setColoringAttributes (col_hand);
Sphere hand = new Sphere (0.08f, app_hand);
tg_hand.addChild(hand);
tg_oben.addChild(tg_schulter);
tg_oben.addChild(tg_oberArm);
tg_unten.addChild(tg_elle);
tg_unten.addChild(tg_unterArm);
tg_unten.addChild(tg_hand);
tg_oben.addChild(tg_unten);
Behavior_Oberarm myRotationBehavior1 =
new Behavior_Oberarm(tg_oben);
Behavior_Unterarm myRotationBehavior2 =
new Behavior_Unterarm(tg_unten);
myRotationBehavior1.setSchedulingBounds(new BoundingSphere());
myRotationBehavior2.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myRotationBehavior1);
objRoot.addChild(myRotationBehavior2);
22
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
// Optimierung des Szenengraphs
objRoot.compile();
return objRoot;
}
public RoboterArm()
{
// Erstellung eines SimpleUniverse nach Vorgabe
// aus dem Sun Tutorial
setLayout(new BorderLayout());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas3D = new Canvas3D(config);
add("Center", canvas3D);
BranchGroup scene = createSceneGraph();
// SimpleUniverse
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph(scene);
}
public static void main(String[] args)
{
Frame frame = new MainFrame(new RoboterArm(), 256, 256);
}
}
23
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Quell-Code AxenColorCubeItnter.java
/* Name: AxenColorCubeInter
*
* Autor: Frank Krack
* Datum: 16. Oktober 2002
*
* Das Programm dient zur Demonstration einfacher
* geometrischer Transformationen.
* Der Würfel wird durch drücken verschiedene Tasten
* unterschiedliche Axen gedreht.
*
* x --> dreht den Würfel mit 45 Grad um X-Achse
* y --> dreht den Würfel mit 45 Grad um Y-Achse
* z --> dreht den Würfel mit 45 Grad um Z-Achse
* c --> dreht den Würfel um 2 Achsen
*
1. Drehumg mit 45 Grad um X-Achse
*
2. Drehung mit 45 Grad um Y-Achse
* a --> dreht den Würfel um 2 Achsen
*
1. Drehung mit 45 Grad um Y-Achse
*
2. Drehung mit 45 Grad um X-Achse
* n --> bringt den Würfel in Ausgangsstellung
*/
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.util.Enumeration;
24
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
//
AxenColorCube erstellt einen ColorCube mit einem
//
eingebetteten Koordinatensystem
public class AxenColorCubeInter extends Applet
{
public class Behavior_Tastatur extends Behavior
{
private TransformGroup targetTG;
private WakeupOnAWTEvent lauscher =
new WakeupOnAWTEvent (KeyEvent.KEY_PRESSED);
// erstellt Behavior_Tastatur
Behavior_Tastatur(TransformGroup targetTG)
{
this.targetTG = targetTG;
}
// Initialisierung behavior
public void initialize()
{
// Erignis zum Abarbeitungsbeginn
this.wakeupOn(lauscher);
}
// diese Funktion wird von Java3D bei Eintritt
// des Erignis aufgerufen
public void processStimulus(Enumeration criteria)
{
TransformGroup tg_temp = new TransformGroup();
// Transformationsmatrizen
Transform3D rotation = new Transform3D();
Transform3D rotate_a = new Transform3D();
Transform3D rotate_b = new Transform3D();
25
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
KeyEvent key = (KeyEvent) lauscher.getAWTEvent()[0];
char c = key.getKeyChar();
switch (c)
{
case 'x': // Drehung des Würfels um die
// X-Achse mit 45 Grad
rotation.rotX(Math.PI/4.0d);
targetTG.setTransform(rotation);
break;
case 'y': // Drehung des Würfels um die
// Y-Achse mit 45 Grad
rotation.rotY(Math.PI/4.0d);
targetTG.setTransform(rotation);
break;
case 'z': // Drehung des Würfels um die
// Z-Achse mit 45 Grad
rotation.rotZ(Math.PI/4.0d);
targetTG.setTransform(rotation);
break;
case 'c': // Drehung des Würfels um 2 Achsen
// 1. Drehung um X-Achse mit 45 Grad
// 2. Drehung um y-Achse mit 45 Grad
rotate_a.rotX(Math.PI/4.0d);
rotate_b.rotY(Math.PI/4.0d);
rotate_a.mul(rotate_b);
targetTG.setTransform(rotate_a);
break;
case 'a': // Drehung des Würfels um 2 Achsen
// 1. Drehung um Y-Achse mit 45 Grad
// 2. Drehung um X-Achse mit 45 Grad
26
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
rotate_a.rotY(Math.PI/4.0d);
rotate_b.rotX(Math.PI/4.0d);
rotate_a.mul(rotate_b);
targetTG.setTransform(rotate_a);
break;
case 'n': // Würfel in Ausgangsstellung
// zurückbringen
rotation.rotX(0.0f);
targetTG.setTransform(rotation);
break;
case 'q': // Drehung des Würfels um die erste
// Quadrantenhalbierende mit 45 Grad
rotation.setRotation (new AxisAngle4d (1,1,1,
Math.toRadians (45.0d)));
targetTG.setTransform(rotation);
break;
}
this.wakeupOn (lauscher);
}
} // Ende der Klasse Behavior_Tastatur
public BranchGroup createSceneGraph()
{
// Wurzel des Szenengraphs
BranchGroup objRoot = new BranchGroup();
TransformGroup objRotate = new TransformGroup();
objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRoot.addChild(objRotate);
Appearance app = new Appearance();
// Y-Achse des Koordinatensystems
27
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
Cylinder yAxe = new Cylinder (0.025f, 2.0f, app);
objRotate.addChild(yAxe);
// X-Achse des Koordinatensystems
Cylinder xAxe = new Cylinder (0.025f, 2.0f, app);
Transform3D rotXaxis = new Transform3D();
rotXaxis.rotZ (Math.PI / 2);
TransformGroup rotXgroup = new TransformGroup (rotXaxis);
rotXgroup.addChild(xAxe);
objRotate.addChild(rotXgroup);
// Z-Achse des Koordinatensystems
Cylinder zAxe = new Cylinder (0.025f, 2.0f, app);
Transform3D rotZaxis = new Transform3D();
rotZaxis.rotX (Math.PI / 2);
TransformGroup rotZgroup = new TransformGroup (rotZaxis);
rotZgroup.addChild(zAxe);
objRotate.addChild(rotZgroup);
objRotate.addChild(new ColorCube(0.4));
Behavior_Tastatur myRotationBehavior1 =
new Behavior_Tastatur(objRotate);
myRotationBehavior1.setSchedulingBounds(new BoundingSphere());
objRoot.addChild(myRotationBehavior1);
// Optimierung des Szenengraphs
objRoot.compile();
return objRoot;
}
public AxenColorCubeInter()
{
// Erstellung eines SimpleUniverse nach Vorgabe
// aus dem Sun Tutorial
setLayout(new BorderLayout());
28
Transformationen
Frank Krack
153 973
Seminar
Grafikprogrammierung mittels Java3D
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas3D = new Canvas3D(config);
add("Center", canvas3D);
BranchGroup scene = createSceneGraph();
// SimpleUniverse
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph(scene);
}
public static void main(String[] args)
{
Frame frame = new MainFrame(new AxenColorCubeInter(), 256, 256);
}
}
29
Herunterladen