Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Algorithmen » Abbildungsmatrix für Isometrie » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen Abbildungsmatrix für Isometrie
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Tommy1234
Foren As


Dabei seit: 12.07.2015
Beiträge: 93

Abbildungsmatrix für Isometrie Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo,

ich habe ein aus 3x3 Feldern bestehendes isometrisches Spielfeld (Kachelgröße:128x64) auf den Bildschirm gezeichnet und möchte nun mit der Maus auslesen können, auf welche Kachel (z.B. 1,2) ich geklickt habe.

Hier ist zunächst einmal der Code:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
public void loadLevel(){
for(int x = 0;x<mapWidth;x++){
			for(int y = 0;y<mapHeight;y++){
				int mapx = (x+y)*64;
				int mapy = (x-y)*32+64;
				p[x][y] = new Point(mapx,mapy);
			}
		}
	}


03.10.2016 12:28 Tommy1234 ist offline Beiträge von Tommy1234 suchen Nehmen Sie Tommy1234 in Ihre Freundesliste auf
Tommy1234
Foren As


Dabei seit: 12.07.2015
Beiträge: 93

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Wurde beim schreiben gestört.... .

Also mapx bzw. mapy bestehen aus x-y bzw. x+y.
Das kann man als Matrix sehen in der Form

1 -1
1 1.

Nun ist ja die Abbildungsmatrix A*s + v = x;

Wobei A die o.g. Matrix ist, s ist (64,32) und v ist die Translation hier: (128,0).

Wenn man mapx bzw. mapy umformt kommt man auf den Kachelindex:

tilex = (mapx/64 + mapy/32)/2;
tiley = (mapy/32 - mapx/64)/2;

Das geteilt durch zwei kommt zustande wenn man mit geraden Werten rechnen will, denn die Matrix liefert 0.5. Also mal 2.

Wie im Code oben habe ich mapx bzw. mapy durch mousex bzw. mousey ersetzt.

Aber, wenn man die Applikation dann startet und testet stimmt das Ergebnis nur teilweise, denn es wird nur an bestimmten Punkten in einer Kachel korrekt angezeigt je nachdem wo man halt auf die Kachel klickt und in derselben Kachel auch falsch.

D.h. ich lieg nicht so ganz falsch aber ich finde den mathematischen Fehler nicht. Braucht man noch sowas wie eine Translationsmatrix oder geht das völlig anders?

Sorry wegen dem ersten unpräzisen post.

Gruß Tommy
03.10.2016 20:09 Tommy1234 ist offline Beiträge von Tommy1234 suchen Nehmen Sie Tommy1234 in Ihre Freundesliste auf
eulerscheZahl eulerscheZahl ist männlich
Foren Gott


Dabei seit: 04.01.2013
Beiträge: 2.859

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ehrlich gesagt verstehe ich immer noch nicht, was genau du machst.
Könntest du zumindest so viel Code anhängen, dass ich dein Programm ausführen und testen kann?

__________________
Syntax Highlighting fürs Board (Link)
04.10.2016 07:13 eulerscheZahl ist offline Beiträge von eulerscheZahl suchen Nehmen Sie eulerscheZahl in Ihre Freundesliste auf
Tommy1234
Foren As


Dabei seit: 12.07.2015
Beiträge: 93

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hier der Code:


Game Klasse:

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:
package main;

import java.awt.*;
import java.awt.image.*;

import javax.swing.JFrame;

public class Game extends Canvas implements Runnable{

	private static final long serialVersionUID = 1L;
	
	private final int WIDTH = 320;
	private final int HEIGHT = 160;
	private final int SCALE = 3;
	
	private Thread thread;
	private JFrame frame;
    private Mouse mouse;
    private boolean running = false;
    
    private Level level;
    
	public Game() {
		
		Dimension size = new Dimension(WIDTH*SCALE,HEIGHT*SCALE);
		setPreferredSize(size);
		
		frame = new JFrame();
		level = new Level(3,3);
		mouse = new Mouse();
		addMouseListener(mouse);
	}
	
	public synchronized void start(){
		running = true;
        thread = new Thread(this,"Display");
        thread.start();
    }
	
	public synchronized void stop(){
		running = false;
        try {
			thread.join();
		} catch (InterruptedException e) {e.printStackTrace();}
    }
    
    public void run() {
        
    	long lastTime = System.nanoTime();
    	long timer = System.currentTimeMillis();
        final double ns = 1000000000.0 / 60.0;
        double delta = 0;
        int updates = 0;
        int frames = 0;
        while(running){
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            while(delta>=1){
                update();
                updates++;
                delta--;
            }
            render();
            frames++;
        
            if(System.currentTimeMillis()-timer>1000){
                timer+=1000;
                frame.setTitle("UPS:   " + updates + "   FPS:   " + frames);
                frames = 0;
                updates = 0;
            }
        }
        stop();
    }
    
	public void update(){
		
		level.update();
    }
    
    public void render(){
    	
    	BufferStrategy bs = getBufferStrategy();
        if(bs == null){
            this.createBufferStrategy(3);
            return;
        }
        
        Graphics g = bs.getDrawGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        level.render(g);
        g.dispose();
        bs.show();
    }
    
    public static void main(String[] args) {
		
		Game game = new Game();
		game.setFocusable(true);
		game.requestFocus();
		game.frame.add(game);
		game.frame.pack();
		game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		game.frame.setLocationRelativeTo(null);
		game.frame.setVisible(true);
		
		game.start();

	}
}CODE]

Dann die Level Klasse:

[CODE]package main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;

public class Level {

	private int mapWidth;
	private int mapHeight;
	
	private int tilex;
	private int tiley;
	
	private Point[][] p;
	
	
	public Level(int mapWidth,int mapHeight) {
		this.mapWidth = mapWidth;
		this.mapHeight = mapHeight;
		p = new Point[mapWidth][mapHeight];
		loadLevel();
	}
	
	public void loadLevel(){
		for(int x = 0;x<mapWidth;x++){
			for(int y = 0;y<mapHeight;y++){
				int mapx = (x-y)*64+128;
				int mapy = (x+y)*32;
				p[x][y] = new Point(mapx,mapy);
			}
		}
	}
	
	public void update(){
		
		tilex = (((Mouse.mousex)/64+((Mouse.mousey)/32))/2);
		tiley = ((((Mouse.mousey)/32-(Mouse.mousex)/64))/2);
		System.out.println(" x   "+tilex + "  y  " + tiley);
		
	}
	
	public void render(Graphics g){
		for(int x = 0;x<mapWidth;x++){
			for(int y = 0;y<mapHeight;y++){
				//int mapx = (x-y)*32;
				//int mapy = (x+y)*16;
				//g.drawImage(gras, mapx, mapy, null);
				
				g.setColor(Color.BLACK);
				g.drawLine(p[x][y].x,p[x][y].y+32,p[x][y].x+64,p[x][y].y);
				g.drawLine(p[x][y].x+64,p[x][y].y,p[x][y].x+128,p[x][y].y+32);
				g.drawLine(p[x][y].x+128,p[x][y].y+32,p[x][y].x+64,p[x][y].y+64);
				g.drawLine(p[x][y].x+64,p[x][y].y+64,p[x][y].x,p[x][y].y+32);
			}
		}
	}

}


Und noch die Maus:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
package main;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Mouse extends MouseAdapter{

	public static int mousex,mousey;
	
	public void mouseClicked(MouseEvent e) {
		
		mousex = e.getX();
		mousey = e.getY();
	}
}


Ok das sollte laufen.
04.10.2016 08:09 Tommy1234 ist offline Beiträge von Tommy1234 suchen Nehmen Sie Tommy1234 in Ihre Freundesliste auf
eulerscheZahl eulerscheZahl ist männlich
Foren Gott


Dabei seit: 04.01.2013
Beiträge: 2.859

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Jetzt verstehe ich erst, wie dein Spielfeld aussieht.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
public void update() {
	double px = Mouse.mousex;
	double py = Mouse.mousey;
	double dx = (32.0 / 64.0 * px - py + 32 * mapHeight) / (2 * 32.0 / 64.0);
	double dy = -(-32.0 / 64.0 * px - py + 32 * mapHeight) / (4 * 32.0 / 64.0);

	tilex = (int) dx / 64;
	tiley = (int) dy / 32;
	System.out.println("mx = " + Mouse.mousex + "  my = " + Mouse.mousey + "  x = " + tilex + "  y = " + tiley + "  dx = " + dx + "  dy = " + dy);
}


__________________
Syntax Highlighting fürs Board (Link)
04.10.2016 09:44 eulerscheZahl ist offline Beiträge von eulerscheZahl suchen Nehmen Sie eulerscheZahl in Ihre Freundesliste auf
Tommy1234
Foren As


Dabei seit: 12.07.2015
Beiträge: 93

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Noch ne Frage :

Wie bekomme ich jetzt den Ursprung nach oben also in P(192/0), so das die Kachel oben in der Mitte 0,0 ist????
04.10.2016 10:15 Tommy1234 ist offline Beiträge von Tommy1234 suchen Nehmen Sie Tommy1234 in Ihre Freundesliste auf
eulerscheZahl eulerscheZahl ist männlich
Foren Gott


Dabei seit: 04.01.2013
Beiträge: 2.859

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Die faule Lösung: x-Achse nachträglich umdrehen.
code:
1:
tilex = mapHeight - 1 - (int) dx / 64;


__________________
Syntax Highlighting fürs Board (Link)
04.10.2016 10:25 eulerscheZahl ist offline Beiträge von eulerscheZahl suchen Nehmen Sie eulerscheZahl in Ihre Freundesliste auf
Tommy1234
Foren As


Dabei seit: 12.07.2015
Beiträge: 93

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Danke!!
04.10.2016 12:15 Tommy1234 ist offline Beiträge von Tommy1234 suchen Nehmen Sie Tommy1234 in Ihre Freundesliste auf
Tommy1234
Foren As


Dabei seit: 12.07.2015
Beiträge: 93

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Sorry muss nochmal altes Thema aufgreifen.

Der Punkt(0,0) liegt bei mir auf x + 200.
Aber trotz Drehung wird's Seitenverkehrt angezeigt.
Ansonsten geht's.
Kein Plan warum???
02.10.2017 20:13 Tommy1234 ist offline Beiträge von Tommy1234 suchen Nehmen Sie Tommy1234 in Ihre Freundesliste auf
Tommy1234
Foren As


Dabei seit: 12.07.2015
Beiträge: 93

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ok, dieses Thema hat sich fast erledigt, denn....

Das mit dem richtigen Tile anklicken habe ich jetzt geschafft: Jetzt versuche ich eine Einheit auf dem isometrischen Grid zu markieren.
Das Grid ist 200x200 groß, die Einheit steht auf Position 0,50 auf dem Grid und wird mittels isometrischer Umrechnung darauf platziert. Um die Einheit herum habe ich ein Rechteck gezeichnet mit iso-Einheit-x bzw. y und möchte nun abfragen, ob mein Mauszeiger(Klick) im Rechteck liegt, wenn ja wird markiert, andernfalls nicht.

Doch es will irgendwie nicht.

Vielleicht kann mir jemand helfen.

Hier Code + Screenshot(dort wo der Mauszeiger ist klicke ich hin):

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
if(unit!=null){
			int isox = (boundingBox.y - boundingBox.x)*2;
			int isoy = (boundingBox.x + boundingBox.y)*1;
			Rectangle box = new Rectangle(isox,isoy,width,height);
			if(MouseInput.left && box.contains(tilex,tiley)){
				marked = true;
				
			}
			System.out.println(box.x+"   "+MouseInput.mousex);
			g.setColor(Color.RED);
			g.drawRect(box.x,box.y,width,height);
			if(MouseInput.left && !box.contains(tilex,tiley)){
				marked = false;
			}
			if(marked){
				g.setColor(Color.GREEN);
				g.fillRect(box.x,box.y,width,5);
			}
			
			plot(unit,width,height,figure,isox-16+400,isoy-16,g);
		}
	} 

Tommy1234 hat dieses Bild (verkleinerte Version) angehängt:
2017-10-03.png

03.10.2017 11:33 Tommy1234 ist offline Beiträge von Tommy1234 suchen Nehmen Sie Tommy1234 in Ihre Freundesliste auf
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
Informatiker Board » Themengebiete » Praktische Informatik » Algorithmen » Abbildungsmatrix für Isometrie