Drehen und Spiegeln

Aus einem unveränderten Magischen Quadrat, das aus den Zahlen von 1 bis zu dem Quadrat seiner Seitenlänge besteht, lassen sich allein durch Drehen und Spiegeln schon 8 verschiedene Quadrate erstellen.

2 9 4
7 5 3
6 1 8

nicht gedreht und nicht gespiegelt, Original

4 9 2
3 5 7
8 1 6

Original nur gespiegelt

6 7 2
1 5 9
8 3 4

Original um 90° im Uhrzeigersinn bzw. 270° mathematisch positiv gedreht, nicht gespiegelt

2 7 6
9 5 1
4 3 8

Original um 90° im Uhrzeigersinn bzw. 270° mathematisch positiv gedreht und gespiegelt

8 1 6
3 5 7
4 9 2

Original um 180° gedreht, nicht gespiegelt

6 1 8
7 5 3
2 9 4

Original um 180° gedreht und gespiegelt

4 3 8
9 5 1
2 7 6

Original um 270° im Uhrzeigersinn bzw. 90° mathematisch positiv gedreht, nicht gespiegelt

8 3 4
1 5 9
6 7 2

Original um 270° im Uhrzeigersinn bzw. 90° mathematisch positiv gedreht und gespiegelt

Trotz Drehen und Spiegeln bleiben die Quadrate magisch, da nichts an den Zahlen selbst geändert wird.

Umsetzung in Delphi

Es muss zunächst erst einmal eine Prozedur geben, die ermittelt, wie gespiegelt und gedreht werden muss. Es muss also eine Variable geben, die 8 verschiedene Werte zurückgibt für die 8 Möglichkeiten. Die Prozedur muss die Auswahl der RadioGroup fürs Drehen, der RadioGroup für die Drehrichtung und dem Rahmen mit dem Kontrollkästchen in eine Variable schreiben.

Die Variable in der Prozedur GetRotIndex kann folgende Werte annehmen:

Wert Gedreht im Uhrzeigersinn Gedreht in mathematisch positiver Drehrichtung Gespiegelt
0 -
1 90° 270° -
2 180° 180° -
3 270° 90° -
4 x
5 90° 270° x
6 180° 180° x
7 270° 90° x

Wird das Magische Quadrat nicht gespiegelt, so stimmt der RotaionIndex mit dem Index der RadioGroup für das Drehen überein. Wird in mathematisch positiver Drehrichtung gedreht, muss man den Wert durch eine Case-Verzweigung zuweisen. Wird Gespiegelt, muss der RotationIndex noch einmal um 4 vergrößert werden. Dieses Verfahren äußert sich in folgendem Code:

var
  RotationIndex:Byte;

procedure tfrmCreateMagsquar.GetRotIndex;

begin
  if rgdirection.itemindex=0 then
  begin
    rotationindex:=rgrotate.ItemIndex;
  end
  else
  begin
    case rgrotate.ItemIndex of
      0,2:rotationindex:=rgrotate.ItemIndex;
      1:rotationindex:=3;
      3:rotationindex:=1;
    end;
  end;
  if cbmirror.checked=True then rotationindex:=rotationindex+4;
end;

Mehr dazu kann man bei den Ausgabe-Algorithmen finden.