jaja, mal versuche ich 3d transformationen zu verstehen und lande kurz darauf wieder im anfänger forum… aber naja, folgendes:
Ich dachte eigentlich bei der erzeugung des “cube” arrays setze ich eigentlich nur referenzen auf die zuvor erstellen variablen.
wenn ich jedoch ein objekt aus cube[x] verändere, (x, y, z oder sonstiges) bleibt die urvariable davon unberührt… wieso? Sind das
jetzt doch kopien, oder wie?
der code:
[spoiler]Point3D frontTopRight = new Point3D(30, 30, 30); Point3D frontTopLeft = new Point3D(10, 30, 30); Point3D frontBottomLeft = new Point3D(10, 10, 30); Point3D frontBottomRight = new Point3D(30, 10, 30); Point3D backTopLeft = new Point3D(10, 30, 10); Point3D backTopRight = new Point3D(30, 30, 10); Point3D backBottomLeft = new Point3D(10, 10, 10); Point3D backBottomRight = new Point3D(30, 10, 10); Point3D cube[] = { frontTopRight, frontTopLeft, frontBottomLeft, frontBottomRight, backTopLeft, backTopRight, backBottomLeft, backBottomRight };[/spoiler]
cube** = Point3D.parseMatrix(R.multiply(cube**));
cube**.print(null);
}```
[/spoiler]
Und bei print (das ist einfach ein sysoutout) kommen auch die richtigen werte...
aber wenn ich später die selben punkte male :
nutzung
[spoiler]
``` drawLine(backTopRight, backTopLeft, g);
drawLine(backBottomRight, backBottomLeft, g);
drawLine(backTopRight, backBottomRight, g);
drawLine(backTopLeft, backBottomLeft, g);
drawLine(frontTopRight, frontTopLeft, g);
drawLine(frontBottomRight, frontBottomLeft, g);
drawLine(frontTopRight, frontBottomRight, g);
drawLine(frontTopLeft, frontBottomLeft, g);
drawLine(backTopRight, frontTopRight, g);
drawLine(backTopLeft, frontTopLeft, g);
drawLine(backBottomLeft, frontBottomLeft, g);
drawLine(backBottomRight, frontBottomRight, g);
[/spoiler]
sind dort wieder ganz andere (also die alten) werte… (sysout verräts)
edit
mit == überprüft man doch ob die objekte die auf die selbe referenz verweisen, oder?
jedenfalls, cube[5] == backTopRight ergibt false.
Ich bin mir nicht sicher, ob ich dein Problem verstanden habe - aber vllt hilft ja eine allgemeine Erklärung:
Wenn du primitive Datentypen (int, boolean, char, …) an eine Methode übergibst, dann übergibst du den Wert und keine referenz. Deswegen:
public void test(int a) {
a = 5;
}
// Der Aufruf in einer anderen Methode:
int abc = 10;
test(abc); // Test ist weiterhin 10 und nicht 5!
abc wird hier nicht verändert! D.h. die Methode kann keine Auswirkung auf den übergebenen Parameter haben. Anders sieht es bei komplexen Datentypen (Objekte [dazu gehören auch Arrays!]):
public void someMethod(MyObject obj) {
obj.setAnything(5);
obj = null;
}
// Der aufruf später:
MyObject sample = new MyObject();
someMethod(sample);
hier würden Änderungen an dem sample-Objekt stattfinden, sofern die Methode setAnything etwas daran ändert. Allerdings kann die Methode so nicht bewirken, dass sample null ist. Der Methode someMethod wird lediglich eine Referenz auf das Objekt übergeben. Durch dereferenzierung (machst du beim Aufrufen einer Methode) kannst du das Objekt verändern. Da es lediglich eine Referenz und kein Pointer ist, kannst du die Ursprüngliche Variable (sample) nicht beeinflussen.
ahhhhhh sry leute das ist erledigt.
Ich habe auf die „falschen“ koordinaten zugegriffen - und zwar hab ich dir koordinaten 2 mal, einmal in Point3D und einmal in Matrix, wovon point3D erbt.
in point3d habe ich vergessen die werte zu aktualisieren.
so einfach kann sein.
*** Edit ***
Nope, doch nicht.
Hab die aktualisierung eingebaut und trozdem.
anscheinend werden im array wirklich neue objekte angelegt…
aber warum?
Bei
cube** = Point3D.parseMatrix(R.multiply(cube**));
wird mit ziemlicher sicherheit ein neues Objekt erzeugt. Wie diese “parseMatrix”-Methode aussieht, und was sie macht, und wozu sie gut ist, wäre sicher interessant.
Aber ganz allgemein stellt sich diese Frage bei diesem Thema immer. Und ich habe schon mehrfach überlegt und angesetzt und gehadert, aber es ist schwierig, eine “gute”, allgemeingültige Lösung zu finden. Wenn man eine Klasse “Matrix” hat, und dort eine Methode einbaut wie multiply(Point3D p), dann gibt es da einige Freiheitsgrade:
Die Methode könnte direkt den übergebenen Punkt verändern. Das kann im Einzelfall schwierig sein, oder ggf. sogar zu unerwünschten Effekten führen. Vielleicht will man sogar, dass Point3D immutable ist, um genau solche Effekte zu verhindern.
Die Methode könnte einen neuen Punkt (mit den neuen Koordinaten) zurückgeben. Wenn man viele Punkte transformieren will, ist das vielleicht nicht gewünscht, weil viele Objekte neu erzeugt werden müssen.
Man könnte eine Methode schreiben wie Point3D multiply(Point3D input, Point3D result), die beides kann: Sie liest den Punkt ‘input’ und schreibt die Ergebnisse (also die geänderten Koordinaten) in ‘result’, und liefert auch ‘result’ zurück. Wenn als ‘result’ einfach ‘null’ übergeben wird, erstellt sie selbst den neuen Punkt, den sie dann zurückgibt. Allerdings ist das von der API her vielleicht nicht so schön wie die ersten beiden Alternativen.
Die Erzeugung von vielen neuen Objekten (aus 2.) ist heute bei weitem nicht mehr so problematisch wie zu Java 1.3-Zeiten. Der GC und der JIT mit Escape Analysis sind heute so gut, dass das wohl nur noch selten eine Rolle spielt. Aber meistens sind solche 3D-Sachen eben gerade der letzte Bereich, der noch wirklich zeitkritisch ist. Deswegen ist das ganze recht schwierig. Du kannst dir ja mal verschiedene andere Implementierungen ansehen, wie die Matrix4f aus javax.vecmath, oder die Matrix4f aus LWJGL, und dich davon inspirieren lassen - im positiven oder negativen Sinn (vecmath verwendet z.B. public fields - aber das hat(te) eben alles seine Gründe).