Hallo,
ich habe mir ein kleines Programm geschrieben um die Vektor-Matrix-Multiplikationen mit Rotationsmatritzen aus der Mathe-Vorlesung besser nachvollziehen zu können. Grundidee ist, dass ein Würfel aus 8 Punkten im Raum (Vektoren) besteht und wenn ich den ganzen Würfel um einen bestimmten Winkel rotieren lassen möchte, dann muss ich alle Vektoren mit einer bestimmten Rotationsmatrix multiplizieren. Das zu implementieren war jetzt auch nicht weiter wild, aber nun bin ich auf ein (warscheinlich sehr banals) Problem gestoßen und bekomme es irgendwie nicht hin. Also ich habe jetzt eine Art animations-Methode geschrieben, die den Würfel jeweils einmal 360° um x-, y- und die z-achse drehen lässt, wobei nach jedem grad rotation eine pause von 100milisekunden eingelegt wird. Rufe ich diese methode im Konstruktor meiner Fensterklasse auf, dann funktioniert auch alles prima... aber wenn ich sie im Action-Listener aufrufe, dann wird erstmal gar nichts gezeichnet... und erst dann wieder wenn die animations-methode komplett durchgelaufen ist. Ich schätze, ich muss dem Fenster dann noch irgendwie sagen, dass es auch jedes mal neugezeichnet werden soll, oder so? Hat da jemand einen Tip?!
Mein Code:
ich habe mir ein kleines Programm geschrieben um die Vektor-Matrix-Multiplikationen mit Rotationsmatritzen aus der Mathe-Vorlesung besser nachvollziehen zu können. Grundidee ist, dass ein Würfel aus 8 Punkten im Raum (Vektoren) besteht und wenn ich den ganzen Würfel um einen bestimmten Winkel rotieren lassen möchte, dann muss ich alle Vektoren mit einer bestimmten Rotationsmatrix multiplizieren. Das zu implementieren war jetzt auch nicht weiter wild, aber nun bin ich auf ein (warscheinlich sehr banals) Problem gestoßen und bekomme es irgendwie nicht hin. Also ich habe jetzt eine Art animations-Methode geschrieben, die den Würfel jeweils einmal 360° um x-, y- und die z-achse drehen lässt, wobei nach jedem grad rotation eine pause von 100milisekunden eingelegt wird. Rufe ich diese methode im Konstruktor meiner Fensterklasse auf, dann funktioniert auch alles prima... aber wenn ich sie im Action-Listener aufrufe, dann wird erstmal gar nichts gezeichnet... und erst dann wieder wenn die animations-methode komplett durchgelaufen ist. Ich schätze, ich muss dem Fenster dann noch irgendwie sagen, dass es auch jedes mal neugezeichnet werden soll, oder so? Hat da jemand einen Tip?!
Mein Code:
Java:
// Würfelfenster.java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Wuefelfenster extends JFrame {
public class Diagramm extends JPanel {
private Vektor3[] wuerfel = {
new Vektor3(0,0,0),
new Vektor3(100,0,0),
new Vektor3(0,100,0),
new Vektor3(100,100,0),
new Vektor3(0,0,100),
new Vektor3(100,0,100),
new Vektor3(0,100,100),
new Vektor3(100,100,100)};
private Vektor3[] rotationswuerfel = new Vektor3[wuerfel.length];
JLabel label = new JLabel("adsasd");
public Diagramm(){
this.reset();
this.setBackground(Color.black);
label.setForeground(Color.white);
this.add(label);
}
private Vektor2 getKoordinatenursprung(){
return new Vektor2(this.getWidth()/2,this.getHeight()/2);
}
private Vektor2 vec2toVec3(Vektor3 vec3){
Vektor2 ku = getKoordinatenursprung();
return new Vektor2(ku.getX() + vec3.getX() + (vec3.getZ()/ 2), ku.getY() - vec3.getY() - (vec3.getZ()/ 2));
}
public void drawLine(Graphics g, Vektor2 a, Vektor2 b){
g.drawLine(a.getX(), a.getY(), b.getX(), b.getY());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
wuerfelZeichnen(g);
}
public void rotierenZ(int grad){
label.setText("Z-Rotation");
for (int i = 0; i<wuerfel.length;i++){
rotationswuerfel[i] = wuerfel[i].rotateZ(grad);
}
}
public void reset(){
label.setText("");
for (int i = 0; i<wuerfel.length;i++){
rotationswuerfel[i] = wuerfel[i];
}
this.repaint();
}
public void rotierenX(int grad){
label.setText("X-Rotation");
for (int i = 0; i<wuerfel.length;i++){
rotationswuerfel[i] = wuerfel[i].rotateX(grad);
}
}
public void rotierenY(int grad){
label.setText("Y-Rotation");
for (int i = 0; i<wuerfel.length;i++){
rotationswuerfel[i] = wuerfel[i].rotateY(grad);
}
}
public void rotierenXYZ(int grad){
label.setText("XYZ-Rotation");
for (int i = 0; i<wuerfel.length;i++){
rotationswuerfel[i] = wuerfel[i].rotateXYZ(grad);
}
}
private void wuerfelZeichnen(Graphics g) {
g.setColor(Color.red);
drawLine(g,vec2toVec3(rotationswuerfel[0]),vec2toVec3(rotationswuerfel[1]));
drawLine(g,vec2toVec3(rotationswuerfel[0]),vec2toVec3(rotationswuerfel[2]));
drawLine(g,vec2toVec3(rotationswuerfel[1]),vec2toVec3(rotationswuerfel[3]));
drawLine(g,vec2toVec3(rotationswuerfel[2]),vec2toVec3(rotationswuerfel[3]));
g.setColor(Color.blue);
drawLine(g,vec2toVec3(rotationswuerfel[0]),vec2toVec3(rotationswuerfel[4]));
drawLine(g,vec2toVec3(rotationswuerfel[1]),vec2toVec3(rotationswuerfel[5]));
drawLine(g,vec2toVec3(rotationswuerfel[2]),vec2toVec3(rotationswuerfel[6]));
drawLine(g,vec2toVec3(rotationswuerfel[3]),vec2toVec3(rotationswuerfel[7]));
g.setColor(Color.green);
drawLine(g,vec2toVec3(rotationswuerfel[4]),vec2toVec3(rotationswuerfel[5]));
drawLine(g,vec2toVec3(rotationswuerfel[4]),vec2toVec3(rotationswuerfel[6]));
drawLine(g,vec2toVec3(rotationswuerfel[5]),vec2toVec3(rotationswuerfel[7]));
drawLine(g,vec2toVec3(rotationswuerfel[6]),vec2toVec3(rotationswuerfel[7]));
}
}
public static void main(String[] args) {
new Wuefelfenster();
}
private Diagramm diagramm = new Diagramm();
private JLabel label = new JLabel("");
public Wuefelfenster(){
this.setBounds(50, 50, 500, 500);
JButton button = new JButton("Rotieren...");
label.setBackground(Color.black);
this.setBackground(Color.black);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
animation();
}
});
this.setLayout(new BorderLayout());
this.add(diagramm,BorderLayout.CENTER);
this.add(button,BorderLayout.SOUTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
animation();
}
private void animation(){
diagramm.reset();
try
{
for (int e=1;e<=4;e++){
for (int i=0;i<=360;i++){
if (e==1) diagramm.rotierenX(i);
else if (e==2) diagramm.rotierenY(i);
else if (e==3) diagramm.rotierenZ(i);
else if (e==4) diagramm.rotierenXYZ(i);
diagramm.repaint();
Thread.currentThread().sleep(10);
}
}
}
catch (InterruptedException e){}
diagramm.reset();
}
}
Java:
//Vector3.java
public class Vektor3 {
private int x;
private int y;
private int z;
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
public Vektor3(int x, int y, int z){
this.x = x;
this.y = y;
this.z = z;
}
private float winkelZuBogenmaß(int winkel){
return (float)(winkel * Math.PI / 180);
}
public Vektor3 rotateZ(int winkel){
float winkelmass = winkelZuBogenmaß(winkel);
int nx = (int)((Math.cos(winkelmass) * this.x) + (-Math.sin(winkelmass)*this.y));
int ny = (int)((Math.sin(winkelmass) *this.x) + (Math.cos(winkelmass)*this.y));
int nz = this.z;
return new Vektor3(nx,ny,nz);
}
public Vektor3 rotateX(int winkel){
float winkelmass = winkelZuBogenmaß(winkel);
int nx = this.x;
int ny = (int)((Math.cos(winkelmass) * this.y) + (-Math.sin(winkelmass)*this.z));
int nz = (int)((Math.sin(winkelmass) *this.y) + (Math.cos(winkelmass)*this.z));
return new Vektor3(nx,ny,nz);
}
public Vektor3 rotateY(int winkel){
float winkelmass = winkelZuBogenmaß(winkel);
int nx = (int)((Math.cos(winkelmass) * this.x) + (-Math.sin(winkelmass)*this.z));
int ny = this.y;
int nz = (int)((Math.sin(winkelmass) *this.x) + (Math.cos(winkelmass)*this.z));
return new Vektor3(nx,ny,nz);
}
public Vektor3 rotateXYZ(int winkel){
return rotateX(winkel).rotateY(winkel).rotateZ(winkel);
}
}
Java:
//Vector2.java
public class Vektor2 {
private int x,y;
public int getX() {
return x;
}
public int getY() {
return y;
}
public Vektor2 (int x, int y){
this.x = x;
this.y = y;
}
}
Zuletzt bearbeitet: