hust ja schon, hatte gehofft dass durch die Beschreibung durch eine Gleichung sich die Endgleichung kürzen lässt.
Falls es jemanden interessieren sollte, noch die Herleitung und das Endergebnis. Es fängt langsam an und wird in der zweiten Hälfte interessanter.
Danke an @ionutbaiu und @Marco13 für die Mithilfe.
Durch @ionutbaiu habe ich die Sache erst durch einen 13 Spaltenvektor betrachtet, und gemerkt dass man die Rotation durch eine Rotationsmatrix gut berechnen kann
[xx][xy]
[yx][yy]
für 90° ist die Rotationsmatrix
[0][1]
[-1][0]
sprich der neue X-Wert ist 0X+1Y und der Y-Wert ist -1X+0*Y, sprich X2=Y und Y2=-X.
Der Punkt (1|2) wäre - wenn man das Array um 90° drehen würde - dann an Position (2|-1).
Arrays mögen aber keine negativen Adressierungen, wie @Marco13 aber passend angemerkt hat.
Das ganze muss noch durch eine Translations-Matrix verrechnet werden, sprich damit sich der größte negative Wert wieder an Position 0|0 befindet.
Eine Translations-Matrix für 90° sieht dann so aus
[xw][xh] → [0][0]
[yw][yh] → [1][0]
Der Y2 Wert würde um Y2+(yw*Breite des Arrays) verschoben werden. Und der X2-Wert gar nicht; xw=0, xh=0.
Für jede Drehung kann man also 2x [2*2] Matrizen aufstellen (Rotation und Translation) und entsprechend die Gleichung für X und Y dazu.
Jetzt kommt der spannende Teil. Ich habe mir die Matrizen nebeneinander aufgeschrieben (links Rotation, rechts Translation) für die 4 Rotationssteps.
0°
[+1][0] - [0][0]
[0][+1] - [0][0]
90°
[0][+1] - [0][0]
[-1][0] - [1][0]
180°
[-1][0] - [1][0]
[0][-1] - [0][1]
270°
[0][-1] - [0][1]
[+1][0] - [0][0]
Dann merkt man
XX und YY haben dabei immer den selben Wert → XX=YY.
XY und YX haben immer den selben invertierten Wert → XY=-YX.
Die Translationsmatrix hat zudem immer an der Stelle den Wert „1“, an der die Rotationsmatrix den Wert „-1“ hat, der Rest ist immer 0.
Die Beziehung der Werte zwischen der Rotationsmatrix und der Translationsmatrix lassen sich mathematisch so beschreiben
f(z)=(z^2-z)/2. Für f(1)=0, f(0)=0, f(-1)=1.
Oder entsprechend die alternative angewandte Informatik Methode von @Marco13.
Schlussendlich ergeben sich daraus die folgenden Gleichungen für X2 und Y2
X2 = X * xx + Y * xy + w * (xx^2-xx)/2 + h * (xy^2-xy)/2
Y2 = X * -xy + Y * xx + w * (xy^2+xy)/2 + h * (xx^2-xx)/2
für yx=-xy; yy=xx; xw=(xx^2-xx)/2; xh=(xy^2-xy)/2
Das ganze etwas gekürzt gibt dann in Code-Form
public int getX(int x, int y, int w, int h) {
return rot1 * (2 * x + w * (rot1 - 1)) / 2 + rot2 * (2 * y + h * (rot2 - 1)) / 2;
}
public int getY(int x, int y, int w, int h) {
return rot1 * (2 * y + h * (rot1 - 1)) / 2 - rot2 * (2 * x - w * (rot2 + 1)) / 2;
}
bzw. in invertierter Form (weil wir nicht das Array drehen, sondern nur so tun als ob wir auf ein gedrehtes Array zugreifen, intern aber auf ein Array in Ursprungsposition zugreifen keuch)
public int getInvX(int x, int y, int w, int h) {
return rot1 * (2 * x - w * (rot1 + 1)) / 2 - rot2 * (2 * y - h * (rot2 + 1)) / 2;
}
public int getInvY(int x, int y, int w, int h) {
return rot1 * (2 * y - h * (rot1 + 1)) / 2 + rot2 * (2 * x + w * (rot2 - 1)) / 2;
}
Das ganze nochmal als verwendbares Codestück
public enum Rotation {
NORTH(0, 1, 0), EAST(1, 0, 1), SOUTH(2, -1, 0), WEST(3, 0, -1);
public final int rot, rot1, rot2;
Rotation(int rot, int rot1, int rot2) {
this.rot = rot;
this.rot1 = rot1;
this.rot2 = rot2;
}
public int getX(int x, int y, int w, int h) {
return rot1 * (2 * x + w * (rot1 - 1)) / 2 + rot2 * (2 * y + h * (rot2 - 1)) / 2;
}
public int getInvX(int x, int y, int w, int h) {
return rot1 * (2 * x - w * (rot1 + 1)) / 2 - rot2 * (2 * y - h * (rot2 + 1)) / 2;
}
public int getY(int x, int y, int w, int h) {
return rot1 * (2 * y + h * (rot1 - 1)) / 2 - rot2 * (2 * x - w * (rot2 + 1)) / 2;
}
public int getInvY(int x, int y, int w, int h) {
return rot1 * (2 * y - h * (rot1 + 1)) / 2 + rot2 * (2 * x + w * (rot2 - 1)) / 2;
}
public int get2X(int x, int y, int w, int h) {
return rot1 == 0 ? rot2 * y + (rot2 == -1 ? h : 0) : rot1 * x + (rot1 == -1 ? w : 0);
}
public int get2Y(int x, int y, int w, int h) {
return rot1 == 0 ? -rot2 * x + (rot2 == 1 ? w : 0) : rot1 * y + (rot1 == -1 ? h : 0);
}
public int get2InvX(int x, int y, int w, int h) {
return rot1 == 0 ? rot2 * y + (rot2 == 1 ? w : 0) : rot1 * x + (rot1 == -1 ? w : 0);
}
public int get2InvY(int x, int y, int w, int h) {
return rot1 == 0 ? rot2 * x + (rot2 == -1 ? h : 0) : rot1 * y + (rot1 == -1 ? h : 0);
}
}
Die unteren mit einer „2“ gelabelten Methoden sind zwar nicht mehr rein mathematische Formeln, aber in der Praxis schneller.
*Edit
Code-Fehler korrigiert