Informatiker Board (http://www.informatikerboard.de/board/index.php)
- Themengebiete (http://www.informatikerboard.de/board/board.php?boardid=1)
-- Praktische Informatik (http://www.informatikerboard.de/board/board.php?boardid=6)
--- Isometrisches Spielfeld die 2te (http://www.informatikerboard.de/board/thread.php?threadid=3438)
Geschrieben von Tommy1234 am 29.01.2017 um 20:17:
Isometrisches Spielfeld die 2te
Hallo,
hab mich mit Transformationen im Grafischen Bereich von Java eingelesen und möchte nun folgendes in Anlehnung an einen früheren Post von mir machen:
Zuerst erzeuge ich ein aus 10x10 Feldern bestehendes Spielfeld als zweidimensionales Rechteckarray.
bestehendes Spielfeld.
In meiner Zeichenmethode transformiere ich zuerst das Koordinatensystem so wie man es in der Schule hatte ( also erster Quadrant ).
Anschließend erzeuge ich eine Rotation und eine Skalierung mittels AffineTransform() und wende die fertige dann auf das Spielfeld an.
Zuletzt nun meine Frage:
Was muss man tun, wenn man erreichen möchte, dass wenn man ein Feld anklickt die richtige Kachel ausgegeben wird?
In meinem letzten Post hat ein sehr fitter Mensch mir eine Formel geliefert, wofür ich auch dankbar bin. Jetzt da ich ein wenig über Transformationen weiß, habe ich mir folgendes gedacht:
Man könnte doch auch einfach die Kachel im ungedrehten Zustand berechnen lassen und diese dann anschließend wieder drehen, sodass , wenn man auf eine Kachel des Isometrischen Spielfeldes klickt eig. die orthogonale Variante berechnet wird aber dennoch das entsprechende isometrische Feld angezeigt wird.
Falls jemand dazu eine Lösung weiß bitte melden, denn bei der Umsetzung harperts noch ziemlich. Zwar kann ich die gängigen Transformationen auf 2-dimensionale Körper anwenden aber die Reihenfolge der einzelnen Transformationen bereitet mir Kopfzerbrechen.
MfG
Tommy
Geschrieben von Tommy1234 am 29.01.2017 um 20:55:
Noch ein kleiner Nachtrag:
Wahrscheinlich hat das mit der Mausposition zu tun, denn die ist ja auf dem isometrischen Spielfeld eine andere als auf dem untransformierten. Wenn man da eine inverse Form braucht weiss ich allerdings nicht wie man diese auf das gesamte Spielfeld anwendet.
Geschrieben von eulerscheZahl am 30.01.2017 um 07:38:
Nur mal, dass ich das richtig verstehe: du bist an der Funktion zur Umrechnung mittels verketteter Transformationen interessiert?
Blau: Koordinaten in Java, schwarz dein Koordinatensystem. Die Frage zielt vor allem auf
![[latex]f^{-1}(x',y')[/latex]](http://www.matheboard.de/latex2png/latex2png.php?f^{-1}(x',y'))
ab.
falls du
![[latex]f(x,y) = t_n(\dots (t_2(t_1(x,y))))[/latex]](http://www.matheboard.de/latex2png/latex2png.php?f(x,y) = t_n(\dots (t_2(t_1(x,y)))))
schon hast: die Transformationen der Reihe nach invertieren und die Reihenfolge umkehren:
![[latex]f^{-1}(x',y') = t_1^{-1}(t_2^{-1}(\dots(t_n^{-1}(x',y'))))[/latex]](http://www.matheboard.de/latex2png/latex2png.php?f^{-1}(x',y') = t_1^{-1}(t_2^{-1}(\dots(t_n^{-1}(x',y')))))
.
Entschuldigung übrigens, dass ich deine Anfragen hier öfter mal ignoriere. Das ist einfach eine Zeitfrage. Wenn jemand eine Dezimalzahl in binär schreiben will, muss ich nicht lange überlegen, bei dir wird es meist aufwendiger.
Geschrieben von Tommy1234 am 30.01.2017 um 07:45:
hhhhh, und ich hab ewig nichts gepostet weil ich dachte ich geh den leuten aufn sack hhhhh
Also zurück zum Thema:
Ja ich bin daran interessiert.
Nun muss man also sowohl die Rotation, als auch die Skalierung invertieren und das ganze dann mittels inverser Matrix abbilden hab ich das richtig verstanden?
mFg
Tommy
Geschrieben von Tommy1234 am 30.01.2017 um 07:49:
Ach ja, wie heißt den die Funktion in Java für die inverse Matrix, denn es gibt da zwei die eine möchte Double Arrays die andere 2 Punkte?
Geschrieben von eulerscheZahl am 30.01.2017 um 08:03:
Was die Java Bibliothek hergibt, weiß ich auch nicht ohne Recherche.
Eben mal reingeschaut: es gibt ein concatenate, mit dem du mehrere verknüpfen kannst.
Mit inverseTransform(Point2D ptSrc, Point2D ptDst) sollte für die Rücktransformation genügen (die Überladung mit Arrays rechnet mehrere Punkte gleichzeitig um, die hast aber nur einen Mauszeiger).
Falls du trotzdem wissen willst, was passiert: die letzte Transformation (also t1 in meiner Formel) wird invertiert. Wenn du das auf den Punkt anwendest, erhältst du einen neuen Punkt. Auf diesen wendest du die inverse von t2 an. Und so weiter.
Geschrieben von Tommy1234 am 30.01.2017 um 19:12:
Jetzt muss ich doch nochmal fragen:
Zum einen wird das Feld ja gemalt und zum anderen wird das Feld berechnet.
Hier mal mein Code für die Zeichen Methode:
| code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
|
public void paintField(Graphics g){
Graphics2D g2 = (Graphics2D) g;
//Das Koordinatensystem auf den ersten Quadranten legen
AffineTransform at = new AffineTransform();
at.setToScale(1, -1);
AffineTransform translate = new AffineTransform();
translate.setToTranslation(1,480-1);
at.preConcatenate(translate);
g2.transform(at);
//die Rotation
rotation = new AffineTransform();
rotation.setToRotation(Math.toRadians(45));
scale = new Affine Transform();
scale.setToScale(2,1);
rotation.preConcatenate(scale);
int mx = Mouse.mousex;
int my = Mouse.mousey;
//die Rotation auf das Shapeobjekt anwenden und zeichnen
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
Shape trans = rotation.createTransformedShape(field[i][j]);
g2.draw(trans);
}
} |
|
Wenn ich jetzt die inverse Form berechnen will brauche ich also:
Point2D p = Rotation.inverseTransform(new Point(mx,my),null); // ??????
Geschrieben von eulerscheZahl am 30.01.2017 um 21:44:
Könntest du bitte immer gleich so viel Code mit angeben, dass ich das in Eclipse reinkopieren und direkt ausführen kann, ohne noch eine GUI und einen MouseListener ergänzen zu müssen?
Das reduziert meinen Arbeitsaufwand und erhöht deine Aussichten auf eine Antwort.
Muss nicht das komplette Programm sein, falls du das nicht veröffentlichen willst oder es zu umfangreich ist. Aber lauffähig sollte es schon sein.
Geschrieben von Tommy1234 am 31.01.2017 um 10:12:
Hier der Code:
| code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
|
package main;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 1L;
private JFrame frame;
private Thread thread;
private Level level;
public Game(int WIDTH,int HEIGHT) {
level = new Level();
this.addMouseListener(new Mouse());
this.setFocusable(true);
frame = new JFrame("Game");
frame.add(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH,HEIGHT);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void start(){
thread = new Thread(this);
thread.start();
}
public void paint(){
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D g2 = (Graphics2D) g;
g2.clearRect(0,0,getWidth(),getHeight());
level.paintField(g2);
//level.update();
g2.dispose();
bs.show();
}
@Override
public void run() {
int MILLIS = 33;
float fps;
try{
while(true){
long startTime = System.currentTimeMillis();
paint();
long stopTime = System.currentTimeMillis()-startTime;
if(stopTime < MILLIS){
Thread.sleep(MILLIS-stopTime);
fps = 1000/MILLIS;
frame.setTitle("FPS : | " + fps);
}
else{
fps = (int) (1000/stopTime);
frame.setTitle("FPS : | " + fps);
}
}
} catch (InterruptedException e) {e.printStackTrace();}
}
public static void main(String[] args) {
Game game = new Game(928,496);
game.start();
}
}
package main;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
public class Level {
private Shape[][] field;
private AffineTransform rotation,rotation1;
private AffineTransform scale,scale1;
public Level() {
field = new Shape[15][15];
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
field[i][j] = new Rectangle(i*32,j*32,32,32);
}
}
}
public void update(){
AffineTransform at = new AffineTransform();
at.setToScale(1, -1);
AffineTransform translate = new AffineTransform();
translate.setToTranslation(1,480-1);
at.preConcatenate(translate);
}
public void paintField(Graphics g){
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
at.setToScale(1, -1);
AffineTransform translate = new AffineTransform();
translate.setToTranslation(1,480-1);
at.preConcatenate(translate);
g2.transform(at);
rotation = new AffineTransform();
rotation.setToRotation(Math.toRadians(45));
int mx = Mouse.mousex;
int my = Mouse.mousey;
int tilex = (mx-(mx%32))/32;
int tiley = (my-(my%32))/32;
rotation1 = new AffineTransform();
rotation1.setToRotation(Math.toRadians(45));
rotation1.preConcatenate(at);
try {
Point2D p = rotation1.inverseTransform(new Point(tilex,tiley),new Point(mx,my));
} catch (NoninvertibleTransformException e) {e.printStackTrace();}
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
Shape trans = rotation1.createTransformedShape(field[i][j]);
g2.draw(trans);
}
}
System.out.println(tilex + " " + tiley);
}
}
package main;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Mouse extends MouseAdapter{
public static int mousex;
public static int mousey;
public static boolean right;
@Override
public void mouseReleased(MouseEvent e) {
mousex = e.getX();
mousey = e.getY();
if(e.getButton()==MouseEvent.BUTTON1){
right = false;
}
}
@Override
public void mouseClicked(MouseEvent e) {
mousex = e.getX();
mousey = e.getY();
if(e.getButton()==MouseEvent.BUTTON1){
right = true;
}
}
}
|
|
Es sind 3 Klassen im package main. MapLooader kannst du erstmal übergehen.
Geschrieben von Tommy1234 am 31.01.2017 um 10:18:
In Zeile 145 muss noch die Skalierung rein :
scale = new AffineTransform();
scale.setToScale(2,1);
rotation.preConcatenate(scale);
und bei der Erzeugung der Rechtecke:
also bei new Rectangle( i * 32 + 174,j * 32 -144,32,32);
das wars.
Geschrieben von Tommy1234 am 31.01.2017 um 10:20:
und bei trans rotation statt rotation1.
das wars aber jetzt.
Geschrieben von eulerscheZahl am 31.01.2017 um 10:25:
| Zitat: |
| bei new Rectangle( i * 32 + 174,j * 32 -144,32,32); |
und wo soll dieses new Rectangle sein?
Aktuell sehe ich die rechte Hälfte eines um 90° gedrehten, nicht gestauchten Gitters (also Höhe und Breite eines Feldes sind gleich).
Geschrieben von Tommy1234 am 31.01.2017 um 14:34:
bei field[i][j] = new Rectangle();
Wenn du Skype hast könnten wir skypen wäre um einiges einfacher....
Geschrieben von eulerscheZahl am 31.01.2017 um 14:38:
In Skype heiße ich eulersche_Zahl. Mein Mirko geht nicht richtig, aber wir können ja auch chatten.
Geschrieben von Tommy1234 am 31.01.2017 um 15:42:
habe ne kontaktanfrage gesendet mit namen Thomas
Forensoftware: Burning Board, entwickelt von WoltLab GmbH