Okay, hier wie versprochen der neue Thread für $title.
@Marco13 hatte mal diesen link gepostet:
http://i.msdn.microsoft.com/dynimg/IC554559.png
wie sich herausgestellt hat waren IC554559.png die x rotation, …60.png die y rotation und 61 die z rotation.
Soweit so gut, ich habe die dinger nach dem selben prinzip implementiert, (ein bisschen zu manuell, aber was solls:)
siehe Hier:
[spoiler]``` public Matrix createRotationDataX(double angle){
if(!(getRows() == 4 && getCols() == 4)){
throw new UnsupportedOperationException(„rotation matrix should have size 4x4“);
}
else{
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);
matrixData[0][0] = 1;
matrixData[0][1] = 0;
matrixData[0][2] = 0;
matrixData[0][3] = 0;
matrixData[1][0] = 0;
matrixData[1][1] = cosAngle;
matrixData[1][2] = -sinAngle;
matrixData[1][3] = 0;
matrixData[2][0] = 0;
matrixData[2][1] = sinAngle;
matrixData[2][2] = cosAngle;
matrixData[2][3] = 0;
matrixData[3][0] = 0;
matrixData[3][1] = 0;
matrixData[3][2] = 0;
matrixData[3][3] = 0;
return this;
}
}
public Matrix createRotationDataY(double angle){
if(!(getRows() == 4 && getCols() == 4)){
throw new UnsupportedOperationException("rotation matrix should have size 4x4");
}
else{
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);
matrixData[0][0] = cosAngle;
matrixData[0][1] = 0;
matrixData[0][2] = sinAngle;
matrixData[0][3] = 0;
matrixData[1][0] = 0;
matrixData[1][1] = 1;
matrixData[1][2] = 0;
matrixData[1][3] = 0;
matrixData[2][0] = -sinAngle;
matrixData[2][1] = 0;
matrixData[2][2] = cosAngle;
matrixData[2][3] = 0;
matrixData[3][0] = 0;
matrixData[3][1] = 0;
matrixData[3][2] = 0;
matrixData[3][3] = 1;
return this;
}
}
public Matrix createRotationDataZ(double angle){
if(!(getRows() == 4 && getCols() == 4)){
throw new UnsupportedOperationException("rotation matrix should have size 4x4");
}
else{
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);
matrixData[0][0] = cosAngle;
matrixData[0][1] = -sinAngle;
matrixData[0][2] = 0;
matrixData[0][3] = 0;
matrixData[1][0] = sinAngle;
matrixData[1][1] = cosAngle;
matrixData[1][2] = 0;
matrixData[1][3] = 0;
matrixData[2][0] = 0;
matrixData[2][1] = 0;
matrixData[2][2] = 1;
matrixData[2][3] = 0;
matrixData[3][0] = 0;
matrixData[3][1] = 0;
matrixData[3][2] = 0;
matrixData[3][3] = 1;
return this;
}
}```[/spoiler]
das problem nun, ich bekomm es nicht hin die punkte eines würfel sowohl um die x als auch um die y achse zu drehen.
Was ich mache ist den punkt erst einmal mit der x und dann mit der y achse zu multiplizieren - das ergebnis: die animation sieht aus als ob
nur um die y achse gedreht werden würde. Was muss man dafür tun?
Wenn ich immer wieder die matrizen multipliziere, wird der winkel ja sozusagen „draufaddiert“. Das heisst ein mehrmaliger aufruf von
rotateAllPointsX(1)
[spoiler] public void rotateAllPointsX(double angle){ Rx.createRotationDataY(Math.toRadians(angle)); frontTopRight = Point3D.parseMatrix(Rx.multiply(frontTopRight)); frontTopLeft = Point3D.parseMatrix(Rx.multiply(frontTopLeft)); frontBottomLeft = Point3D.parseMatrix(Rx.multiply(frontBottomLeft)); frontBottomRight = Point3D.parseMatrix(Rx.multiply(frontBottomRight)); backTopLeft = Point3D.parseMatrix(Rx.multiply(backTopLeft)); backTopRight = Point3D.parseMatrix(Rx.multiply(backTopRight)); backBottomLeft = Point3D.parseMatrix(Rx.multiply(backBottomLeft)); backBottomRight = Point3D.parseMatrix(Rx.multiply(backBottomRight)); }
[/spoiler]
lässt den würfel immer wieder um einen grad weiter drehen.
wie würde man das am besten lösen, immer wieder von neuem zu drehen?
*** Edit ***
-
hat sich erledigt, war nur ein bisschen dummheit ansonsten klappt es so.
-
Ich hab mal ein kleines testprojekt angelegt, [link], aber irgendwie scheint das ganze zu laggen.
ich weiss nicht ob ich das nur so sehe weil ich es programmiert habe, aber vielleicht sind das ja auch diese
„grenzen“ von java? Ich mein, ein 3d spiel… würde man das damit schreiben können?
(jaja, es gibt minecraft - aber da wurde opengl benutzt… ) -
wie baue ich jetzt am besten die „kamera berechnungen“ ein, und kennt einer wieder lesestoff dafür?
-
mein bisheriger code - was muss unbedingt geändert werden? Also nur von der grunstruktur und den berehcnungen usw. Zur erstellung der figuren bastel ich morgen ne klasse „mesh“
de.skysoldier.matrix3d
[spoiler][SPOILER=Matrix.java]```package de.skysoldier.matrix3d;
import java.io.PrintStream;
public class Matrix {
private int rows;
private int cols;
private double matrixData[][];
public Matrix(){
this(new double[1][1]);
}
public Matrix(double matrixData[][]){
this(matrixData.length, matrixData[0].length);
this.matrixData = matrixData;
}
public Matrix(int rows, int cols){
this.rows = rows;
this.cols = cols;
this.matrixData = new double[rows][cols];
this.fill(0);
}
public Matrix multiply(Matrix multiplier){
if(getCols() != multiplier.getRows()){
throw new ArithmeticException("matrices not multipliable! (multiplicand cols (" + getCols() + ") != multiplier rows (" + multiplier.getRows() + ") )");
}
else{
Matrix product = new Matrix(getRows(), multiplier.getCols());
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < multiplier.getCols(); j++){
double n = 0;
for(int k = 0; k < getCols(); k++){ // or multiplier.getRows(); , no difference
n += getCellData(i, k) * multiplier.getCellData(k, j);
}
product.setCellData(i, j, n);
}
}
return product;
}
}
public void print(PrintStream printer){
if(printer != null){
printer.println(toString());
}
else{
System.out.println(toString());
}
System.out.println("");
}
public String toString(){
String dataString = "";
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getCols(); j++){
dataString += matrixData**[j] + " ";
}
dataString += "
";
}
return dataString;
}
public void fill(int n){
for(int i = 0; i < matrixData.length; i++){
for(int j = 0; j < matrixData[0].length; j++){
matrixData**[j] = n;
}
}
}
public int getRows(){
return rows;
}
public int getCols(){
return cols;
}
public double[][] getMatrixData(){
return matrixData;
}
public double getCellData(int row, int col){
return matrixData[row][col];
}
public void setCellData(int row, int col, double n){
matrixData[row][col] = n;
}
public Matrix createRotationDataX(double angle){
if(!(getRows() == 4 && getCols() == 4)){
throw new UnsupportedOperationException("rotation matrix should have size 4x4");
}
else{
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);
matrixData[0][0] = 1;
matrixData[0][1] = 0;
matrixData[0][2] = 0;
matrixData[0][3] = 0;
matrixData[1][0] = 0;
matrixData[1][1] = cosAngle;
matrixData[1][2] = -sinAngle;
matrixData[1][3] = 0;
matrixData[2][0] = 0;
matrixData[2][1] = sinAngle;
matrixData[2][2] = cosAngle;
matrixData[2][3] = 0;
matrixData[3][0] = 0;
matrixData[3][1] = 0;
matrixData[3][2] = 0;
matrixData[3][3] = 0;
return this;
}
}
public Matrix createRotationDataY(double angle){
if(!(getRows() == 4 && getCols() == 4)){
throw new UnsupportedOperationException("rotation matrix should have size 4x4");
}
else{
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);
matrixData[0][0] = cosAngle;
matrixData[0][1] = 0;
matrixData[0][2] = sinAngle;
matrixData[0][3] = 0;
matrixData[1][0] = 0;
matrixData[1][1] = 1;
matrixData[1][2] = 0;
matrixData[1][3] = 0;
matrixData[2][0] = -sinAngle;
matrixData[2][1] = 0;
matrixData[2][2] = cosAngle;
matrixData[2][3] = 0;
matrixData[3][0] = 0;
matrixData[3][1] = 0;
matrixData[3][2] = 0;
matrixData[3][3] = 1;
return this;
}
}
public Matrix createRotationDataZ(double angle){
if(!(getRows() == 4 && getCols() == 4)){
throw new UnsupportedOperationException("rotation matrix should have size 4x4");
}
else{
double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle);
matrixData[0][0] = cosAngle;
matrixData[0][1] = -sinAngle;
matrixData[0][2] = 0;
matrixData[0][3] = 0;
matrixData[1][0] = sinAngle;
matrixData[1][1] = cosAngle;
matrixData[1][2] = 0;
matrixData[1][3] = 0;
matrixData[2][0] = 0;
matrixData[2][1] = 0;
matrixData[2][2] = 1;
matrixData[2][3] = 0;
matrixData[3][0] = 0;
matrixData[3][1] = 0;
matrixData[3][2] = 0;
matrixData[3][3] = 1;
return this;
}
}
}```[/spoiler]
Point3D.java
[spoiler]```package de.skysoldier.matrix3d;
import java.awt.Color;
public class Point3D extends Matrix {
private double x;
private double y;
private double z;
private Color c;
public Point3D(double x, double y, double z){
super(new double[][]{{x},{y},{z},{1}});
this.x = x;
this.y = y;
this.z = z;
this.c = Color.WHITE;
}
public static Point3D parseMatrix(Matrix m){
if(!(m.getRows() == 4 && m.getCols() == 1)){
throw new IllegalArgumentException("Matrix cannot be converted to Point3D");
}
else{
return new Point3D(m.getCellData(0, 0), m.getCellData(1, 0), m.getCellData(2, 0));
}
}
public void update(){
this.x = getCellData(0, 0);
this.y = getCellData(1, 0);
this.z = getCellData(2, 0);
System.out.println(this.x);
}
public void setColor(Color c){
this.c = c;
}
public double getX(){
return x;
}
public double getY(){
return y;
}
public double getZ(){
return z;
}
public void setX(double x){
this.x = x;
setCellData(0, 0, x);
}
public void setY(double y){
this.y = y;
setCellData(1, 0, y);
}
public void setZ(double z){
this.z = z;
setCellData(2, 0, z);
}
public Color getColor(){
return c;
}
}
MatrixTest.java
[spoiler]```package de.skysoldier.matrix3d;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MatrixTest extends JPanel{
Point3D frontTopRight = new Point3D(20, 20, 40);
Point3D frontTopLeft = new Point3D(-20, 20, 20);
Point3D frontBottomLeft = new Point3D(-20, -20, 40);
Point3D frontBottomRight = new Point3D(20, -20, 20);
Point3D backTopLeft = new Point3D(-20, 20, -40);
Point3D backTopRight = new Point3D(20, 20, -40);
Point3D backBottomLeft = new Point3D(-20, -20, -40);
Point3D backBottomRight = new Point3D(20, -20, -20);
Matrix Rx = new Matrix(4, 4);
Matrix Ry = new Matrix(4, 4);
public void rotateAllPointsX(double angle){
Rx.createRotationDataX(Math.toRadians(angle));
frontTopRight = Point3D.parseMatrix(Rx.multiply(frontTopRight));
frontTopLeft = Point3D.parseMatrix(Rx.multiply(frontTopLeft));
frontBottomLeft = Point3D.parseMatrix(Rx.multiply(frontBottomLeft));
frontBottomRight = Point3D.parseMatrix(Rx.multiply(frontBottomRight));
backTopLeft = Point3D.parseMatrix(Rx.multiply(backTopLeft));
backTopRight = Point3D.parseMatrix(Rx.multiply(backTopRight));
backBottomLeft = Point3D.parseMatrix(Rx.multiply(backBottomLeft));
backBottomRight = Point3D.parseMatrix(Rx.multiply(backBottomRight));
}
public void rotateAllPointsY(double angle){
Ry.createRotationDataY(Math.toRadians(angle));
frontTopRight = Point3D.parseMatrix(Ry.multiply(frontTopRight));
frontTopLeft = Point3D.parseMatrix(Ry.multiply(frontTopLeft));
frontBottomLeft = Point3D.parseMatrix(Ry.multiply(frontBottomLeft));
frontBottomRight = Point3D.parseMatrix(Ry.multiply(frontBottomRight));
backTopLeft = Point3D.parseMatrix(Ry.multiply(backTopLeft));
backTopRight = Point3D.parseMatrix(Ry.multiply(backTopRight));
backBottomLeft = Point3D.parseMatrix(Ry.multiply(backBottomLeft));
backBottomRight = Point3D.parseMatrix(Ry.multiply(backBottomRight));
}
public MatrixTest(){
JFrame f = new JFrame();
f.setSize(800, 600);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new BorderLayout());
f.add(this);
f.setVisible(true);
new Thread(new Runnable() {
public void run() {
while(true){
rotateAllPointsX(0.5);
rotateAllPointsY(1);
repaint();
try{Thread.sleep(10);}catch(Exception e){}
}
}
}).start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
g.drawImage(getCubeMesh(), 100, 100, null);
}
public BufferedImage getCubeMesh(){
BufferedImage drawPane = new BufferedImage(500, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) drawPane.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, drawPane.getWidth(), drawPane.getHeight());
g.setColor(Color.WHITE);
for(int i = 0; i < 5; i++){
drawLine(backTopRight, backTopLeft, g, i * 90 + 50, 40);
drawLine(backBottomRight, backBottomLeft, g, i * 90 + 50, 40);
drawLine(backTopRight, backBottomRight, g, i * 90 + 50, 40);
drawLine(backTopLeft, backBottomLeft, g, i * 90 + 50, 40);
drawLine(frontTopRight, frontTopLeft, g, i * 90 + 50, 40);
drawLine(frontBottomRight, frontBottomLeft, g, i * 90 + 50, 40);
drawLine(frontTopRight, frontBottomRight, g, i * 90 + 50, 40);
drawLine(frontTopLeft, frontBottomLeft, g, i * 90 + 50, 40);
drawLine(backTopRight, frontTopRight, g, i * 90 + 50, 40);
drawLine(backTopLeft, frontTopLeft, g, i * 90 + 50, 40);
drawLine(backBottomLeft, frontBottomLeft, g, i * 90 + 50, 40);
drawLine(backBottomRight, frontBottomRight, g, i * 90 + 50, 40);
}
return drawPane;
}
public void drawPixel(double x, double y, Graphics g){
g.drawLine((int) x, (int) y, (int) x, (int) y);
}
public void drawLine(Point3D p1, Point3D p2, Graphics g, int translateX, int translateY){
int x1 = (int) p1.getX() + translateX;
int x2 = (int) p2.getX() + translateX;
int y1 = (int) p1.getY() + translateY;
int y2 = (int) p2.getY() + translateY;
g.drawLine(x1, y1, x2, y2);
}
public static void main(String[] args){
new MatrixTest();
}
}```[/spoiler]
[/SPOILER]