# Click innerhalb eines 45° gekippten Rechtecks



## kneitzel (30. Mrz 2016)

Hallo,

ich habe heute irgendwie einen Hänger. Ich arbeite nebenbei an einem kleinen Spiel, bei dem ich ein 2D Spielfeld aufgebaut habe. Dieses ist aber um 45° gedreht, so dass es sozusagen auf einer Ecke steht.

Ich habe keinerlei Probleme, dieses Spielfeld graphisch darzustellen und die Flächen entsprechend der Notwendigkeiten zu füllen.

Aber jetzt würde ich auch gerne von einem Click auf das Feld kommen. Und da habe ich jetzt im Augenblick gewisse Probleme mit. Das müsste man ja durch eine einfache Transformation um 45° drehen können, so dass man dann wieder den einfachen Standard-Check machen kann.

Und wo ich grade so im Loch sitzt, da finde ich jetzt auch nicht einmal die übersichtlichen Tutorials zu diesen Themen, die es doch garantiert gibt (und die ich in der Vergangenheit ja auch schon gesehen habe).

Kann mir da evtl. grad jemand auf die Sprünge helfen? (Ansonsten schlafe ich da jetzt einfach einmal drüber und morgen wird sich das Problem dann bestimmt auch lösen lassen.)

Vielen Dank,

Konrad


----------



## kneitzel (30. Mrz 2016)

Ich glaube, ich habe es jetzt doch alleine hin bekommen. Ich habe wohl einfach zuviel auf einmal gewollt, aber manchmal macht es Sinn, wirklich alles einfach nur sauber zu trennen und dann immer alles auszublenden, was nicht direkt hinein gehört.

a) Verschiebung, so dass der Nullpunkt zur wirklichen Nullpunkt wird. (Ist nicht ganz so wild, da man die Dreiecke auch so berechnen kann.
b) dann wirklich die Umrechnung von nur einem Punkt betrachten. Dreiecke einmalen, bekannte Winkel und schon geht es los mit Rechtwinkligen Dreiecken:
1) Was man zuerst braucht ist die Hypothenuse - die kann man direkt ausrechnen mit Wurzel aus x^2 + y^2.
2) Dann kann man einen Winkel berechnen über sin(alpha) = y/hypothenuse. Der Winkel ist aber auf der "falschen Seite", aber man hat da noch dass Alpha + Beta = 45° sein müssen.
3) Nun wird es einfach: sin(beta) = y'/Hypothenuse und cos(beta) = x'/Hypothenuse

Damit lassen sich dann alle Koordinaten des Systems umrechnen. Bei einem Mausclick muss dann nur der Mausclick umgerechnet werden und schon kann man die einfachen Vergleiche anwenden.

Falls es jemand interessiert kann ich die Bildchen dazu morgen noch einscannen und hier mit einbringen, so dass die Berechnungen mitverfolgt werden können.


----------



## Meniskusschaden (30. Mrz 2016)

Bin nicht sicher, ob es zu einer pragmatischen Lösung führt, aber vielleicht ist es einfacher, das Rechteck in zwei Dreiecke zu teilen und zu prüfen, ob eines den Punkt enthält. Für die Dreicksprüfung findet man ein paar Ansätze, z.B. dort:
https://prlbr.de/2014/liegt-der-punkt-im-dreieck/
https://www.amazingcode.de/ueberpruefen-ob-punkt-innerhalb-dreieck-mit-p5-js/
Ansonsten wäre die AWT-Klasse Polygon noch sehr bequem, weil sie bereits eine contains-Methode enthält. Weiß aber nicht, ob die performant genug ist.

EDIT: hat sich offenbar zwischenzeitlich erledigt. Vielleicht sind diese Ansätze trotzdem interessant.


----------



## kneitzel (30. Mrz 2016)

Beide Ansätze sind auf jeden Fall interessant. Die Prüfung mit dem Dreieck werde ich mir auf jeden Fall auch einmal ansehen, denn das ist etwas, wo ich hier auch schon drüber sass und irgendwie nicht auf die Lösung gekommen bin.
Und auch die Polygon-Lösung ist prinzipiell interessant wenn man auf Einzelprüfungen zurück gehen muss (Hier würde ich dann immer das noch nicht geprüfte Spielfeld prüfen indem ich die Hälfte prüfe.)

Aber meine aktuelle Lösung ist das, was generell am günstigsten sein dürfte. Die Ausgangspunkte/-daten werden einmalig festgelegt und dann kann man bei einem Mausclick diesen einmal umrechnen und hat dann recht schnell das Feld (wenn ich die Breite eines Feldes habe, dann kann ich die X-Koordinate / Breite rechnen und bekomme das Feld in x-Richtung und das Gleiche in Y-Richtung. (Natürlich noch prüfen, ob die Werte im gültigen Bereich sind.) Das dürfte meines Wissens nach am schnellsten gehen. Hier wären dann maximal eine Optimierung denkbar, indem man von double auf integer wechselt und dann für die höhere Genauigkeit mit einem Faktor arbeitet. Muss man nur gut aufpassen, dass man alle Operationen richtig hat. Aber das kommt dann erst ganz am Ende.

Erster Schritt ist dann erst einmal, die ganzen Transformationen richtig zu haben, da ich ggf. ein großes Spielfeld habe und somit nur einen Ausschnitt bekomme. Der Ausschnitt ist dann evtl. noch vergrößert oder verkleinert. Das muss ich erst einmal so im Code unterbringen, dass es auch wirklich gut lesbar ist und ich das auch in 2 Jahren noch auf Anhieb verstehe


----------



## thecain (30. Mrz 2016)

Du kannst doch einfach den Punkt um 45° rotieren und dann die normale Berechnung machen, als ob es nicht gedreht wäre (nachdem du den Nullpunkt zum Nullpunkt gemacht hast, wie du schriebst.)

also

```
float xnew = p.x * cos(45) - p.y * sin(45);
float ynew = p.x * sin(45) + p.y * cos(45);
```


----------



## JCODA (30. Mrz 2016)

Wie meistens hat die Matheecke eine Lösung dafür! 
Du könntest einfach eine andere Metrik benutzen. Falls es sich um gedrehte Quadrate handelt, würde ich die von der Summennorm/1-Norm induzierte Metrik nehmen. 
Siehe hierzu https://de.wikipedia.org/wiki/Norm_(Mathematik)#Summennorm


----------



## kneitzel (30. Mrz 2016)

@thecain: Super. Danke. Sogar von der Berechnung her noch etwas einfacher als meine hergeleiteten Dreiecke. Genau das hab ich eigentlich die ganze Zeit gesucht. Etwas in der Art hatte ich in Erinnerung und konnte es mir einfach nicht mehr herleiten!

@JCODA: Super. Noch eine Sache, die ich mir später im Detail ansehen werde. Man weiss ja nie, wann man das dann braucht.

Vielen Dank für eure Unterstützung!


----------



## mariane (10. Apr 2016)

Schaue dir mal die Polygone an (mit Rechtecken gehts aber auch, Polygone sind nur flexibler). Dann einfach nur die Methode contains verwenden, also polygon.contains( p ), p ist ein Punkt, z.B. die Position deines Mausklicks (mousePressed (e) mit p = e.getPoint()). Ist der Punkt innerhalb des Polygons, dann true, sonst false. 

LG mariane


----------



## Thallius (10. Apr 2016)

Kannst du nicht deine gesammte Berechnung und Spielemechanik einfach auf ein "normales" Rechteck machen und nur für die Ausgabe das Ganze um 45° drehen?


----------



## kneitzel (10. Apr 2016)

Danke für eure Ideen.
@mariane: Wäre auch eine Idee, aber dann sind viele Polygone einzeln zu prüfen. Aber die Logik für die Berechnung, in welches Kästchen geklickt wurde, habe ich ja jetzt.
@Thallius: Ja, so habe ich es ja. Nur eben musste ich ja die Mausklicks zurück rechnen können auf das jeweilige Kästchen. Aber das habe ich ja über die Rückrechnung der Drehung hinbekommen.

Vielen Dank für eure Unterstützung.

Mit den besten Grüßen,

Konrad


----------

