TurnArray2d() - 2D-Array um 90, 180 und 270 Grad drehen
Verfasst: 29.10.2006 21:22
Mit freundlicher Unterstützung von Kaeru Gaman ist es mir gelungen, meinen Code zu korrigieren. Mit dieser Funktion kann man ein 2dimensionales Array drehen. Funktioniert bei mir auch prima mit Strukturen
Grundvoraussetzungen:
Breite = Höhe
2 Dimensionen
Benutzung:
TurnArray2D(Array-Adresse, Größe der Array-Struktur, Breite des Arrays, Rotationstyp)
TurnArray2D_90(Array-Adresse, Größe der Array-Struktur, Breite des Arrays)
TurnArray2D_180(Array-Adresse, Größe der Array-Struktur, Breite des Arrays)
TurnArray2D_270(Array-Adresse, Größe der Array-Struktur, Breite des Arrays)
ACHTUNG: DREHUNG ERFOLGT IM UHRZEIGERSINN
Grundvoraussetzungen:
Breite = Höhe
2 Dimensionen
Benutzung:
TurnArray2D(Array-Adresse, Größe der Array-Struktur, Breite des Arrays, Rotationstyp)
TurnArray2D_90(Array-Adresse, Größe der Array-Struktur, Breite des Arrays)
TurnArray2D_180(Array-Adresse, Größe der Array-Struktur, Breite des Arrays)
TurnArray2D_270(Array-Adresse, Größe der Array-Struktur, Breite des Arrays)
Code: Alles auswählen
Enumeration
#TA2D_DEGREE_0
#TA2D_DEGREE_90
#TA2D_DEGREE_180
#TA2D_DEGREE_270
EndEnumeration
CompilerIf Defined(__TA2D_XY, #PB_Structure) = 0
Structure __TA2D_XY
X.l
Y.l
EndStructure
CompilerEndIf
CompilerIf Defined(__TA2D_last_strucsize, #PB_Variable) = 0
Global __TA2D_last_strucsize.l
CompilerEndIf
CompilerIf Defined(*__TA2D_buffer, #PB_Variable) = 0
Global *__TA2D_buffer
CompilerEndIf
Procedure TurnArray2D(*array, strucsize.l, width.l, flag.b)
Protected Ring.l
Protected Cell.l
Protected linesize.l
Protected *A1
Protected *A2
Protected *A3
Protected *A4
Protected P.__TA2D_XY
Protected RingRange.l
Protected LineWidth.l
linesize = strucsize * width
If strucsize <> __TA2D_last_strucsize
;Debug "changed __TA2D_last_strucsize from " + Str(__TA2D_last_strucsize) + " to " + Str(strucsize)
*__TA2D_buffer = AllocateMemory(strucsize)
__TA2D_last_strucsize = strucsize
EndIf
RingRange = width / 2 - 1
LineWidth = width - 1
For Ring = 0 To RingRange;nur bis zur Hälfte durchgehen
;ring-ecken vorberechnen
P\X = Ring
P\Y = Ring + LineWidth
*A1 = *array + P\X * linesize + P\X * strucsize
*A2 = *array + P\X * linesize + P\Y * strucsize
*A3 = *array + P\Y * linesize + P\Y * strucsize
*A4 = *array + P\Y * linesize + P\X * strucsize
;{Ursprüngliche Vorberechnung (zum Verständnis) <- falls eigene änderung, diesen code als vorlage nehmen!
; P1\X = Ring
; P1\Y = Ring
; P1\Z = *array + P1\Y * linesize + P1\X * strucsize
;
; P2\X = Ring + LineWidth
; P2\Y = Ring
; P2\Z = *array + P2\Y * linesize + P2\X * strucsize
;
; P3\X = Ring + LineWidth
; P3\Y = Ring + LineWidth
; P3\Z = *array + P3\Y * linesize + P3\X * strucsize
;
; P4\X = Ring
; P4\Y = Ring + LineWidth
; P4\Z = *array + P4\Y * linesize + P4\X * strucsize
;}
For Cell = 0 To LineWidth-1
;im gegensatz zu vorheriger version wird hier jede zelle einfach nur + "dazugerechnet"
*A1 + strucsize
*A2 + linesize
*A3 - strucsize
*A4 - linesize
;neubeschreiben
Select flag
Case #TA2D_DEGREE_90
CopyMemory(*A1, *__TA2D_buffer, strucsize);PUFFER
CopyMemory(*A2, *A1, strucsize)
CopyMemory(*A3, *A2, strucsize)
CopyMemory(*A4, *A3, strucsize)
CopyMemory(*__TA2D_buffer, *A4, strucsize)
Case #TA2D_DEGREE_180
CopyMemory(*A1, *__TA2D_buffer, strucsize);PUFFER
CopyMemory(*A3, *A1, strucsize)
CopyMemory(*__TA2D_buffer, *A3, strucsize)
CopyMemory(*A4, *__TA2D_buffer, strucsize);PUFFER
CopyMemory(*A2, *A4, strucsize)
CopyMemory(*__TA2D_buffer, *A2, strucsize)
Case #TA2D_DEGREE_270
CopyMemory(*A1, *__TA2D_buffer, strucsize);PUFFER
CopyMemory(*A4, *A1, strucsize)
CopyMemory(*A3, *A4, strucsize)
CopyMemory(*A2, *A3, strucsize)
CopyMemory(*__TA2D_buffer, *A2, strucsize)
EndSelect
Next
LineWidth - 2 ;pro Ring zwei weniger vom Ursprung
Next
EndProcedure
Procedure TurnArray2D_90(*array, strucsize.l, width.l)
Protected Ring.l
Protected Cell.l
Protected linesize.l
Protected *A1
Protected *A2
Protected *A3
Protected *A4
Protected P.__TA2D_XY
Protected RingRange.l
Protected LineWidth.l
linesize = strucsize * width
If strucsize <> __TA2D_last_strucsize
*__TA2D_buffer = AllocateMemory(strucsize)
__TA2D_last_strucsize = strucsize
EndIf
RingRange = width / 2 - 1
LineWidth = width - 1
For Ring = 0 To RingRange
P\X = Ring
P\Y = Ring + LineWidth
*A1 = *array + P\X * linesize + P\X * strucsize
*A2 = *array + P\X * linesize + P\Y * strucsize
*A3 = *array + P\Y * linesize + P\Y * strucsize
*A4 = *array + P\Y * linesize + P\X * strucsize
For Cell = 0 To LineWidth-1
*A1 + strucsize
*A2 + linesize
*A3 - strucsize
*A4 - linesize
CopyMemory(*A1, *__TA2D_buffer, strucsize)
CopyMemory(*A2, *A1, strucsize)
CopyMemory(*A3, *A2, strucsize)
CopyMemory(*A4, *A3, strucsize)
CopyMemory(*__TA2D_buffer, *A4, strucsize)
Next
LineWidth - 2
Next
EndProcedure
Procedure TurnArray2D_180(*array, strucsize.l, width.l)
Protected Ring.l
Protected Cell.l
Protected linesize.l
Protected *A1
Protected *A2
Protected *A3
Protected *A4
Protected P.__TA2D_XY
Protected RingRange.l
Protected LineWidth.l
linesize = strucsize * width
If strucsize <> __TA2D_last_strucsize
*__TA2D_buffer = AllocateMemory(strucsize)
__TA2D_last_strucsize = strucsize
EndIf
RingRange = width / 2 - 1
LineWidth = width - 1
For Ring = 0 To RingRange
P\X = Ring
P\Y = Ring + LineWidth
*A1 = *array + P\X * linesize + P\X * strucsize
*A2 = *array + P\X * linesize + P\Y * strucsize
*A3 = *array + P\Y * linesize + P\Y * strucsize
*A4 = *array + P\Y * linesize + P\X * strucsize
For Cell = 0 To LineWidth-1
*A1 + strucsize
*A2 + linesize
*A3 - strucsize
*A4 - linesize
CopyMemory(*A1, *__TA2D_buffer, strucsize)
CopyMemory(*A3, *A1, strucsize)
CopyMemory(*__TA2D_buffer, *A3, strucsize)
CopyMemory(*A4, *__TA2D_buffer, strucsize)
CopyMemory(*A2, *A4, strucsize)
CopyMemory(*__TA2D_buffer, *A2, strucsize)
Next
LineWidth - 2
Next
EndProcedure
Procedure TurnArray2D_270(*array, strucsize.l, width.l)
Protected Ring.l
Protected Cell.l
Protected linesize.l
Protected *A1
Protected *A2
Protected *A3
Protected *A4
Protected P.__TA2D_XY
Protected RingRange.l
Protected LineWidth.l
linesize = strucsize * width
If strucsize <> __TA2D_last_strucsize
*__TA2D_buffer = AllocateMemory(strucsize)
__TA2D_last_strucsize = strucsize
EndIf
RingRange = width / 2 - 1
LineWidth = width - 1
For Ring = 0 To RingRange
P\X = Ring
P\Y = Ring + LineWidth
*A1 = *array + P\X * linesize + P\X * strucsize
*A2 = *array + P\X * linesize + P\Y * strucsize
*A3 = *array + P\Y * linesize + P\Y * strucsize
*A4 = *array + P\Y * linesize + P\X * strucsize
For Cell = 0 To LineWidth-1
*A1 + strucsize
*A2 + linesize
*A3 - strucsize
*A4 - linesize
CopyMemory(*A1, *__TA2D_buffer, strucsize)
CopyMemory(*A4, *A1, strucsize)
CopyMemory(*A3, *A4, strucsize)
CopyMemory(*A2, *A3, strucsize)
CopyMemory(*__TA2D_buffer, *A2, strucsize)
Next
LineWidth - 2
Next
EndProcedure
;#############################
;# HIER BEGINNT DAS BEISPIEL #
;#############################
;initialisieren
OpenConsole()
ConsoleTitle("TurnArray2D example!")
ConsoleCursor(0)
EnableGraphicalConsole(#True)
Global Dim feld.b(4,4)
Restore fielddat
Macro printit(ymul)
For zy = 0 To 4
For zx = 0 To 4
ConsoleLocate(zx, zy + ymul * 6)
Print(Chr(feld(zx,zy)))
Next
Next
EndMacro
;einlesen
For zy = 0 To 4
For zx = 0 To 4
Read feld(zx,zy)
Next
Next
;ausgeben
printit(0)
TurnArray2D_90(@feld(0,0), SizeOf(Byte), 5)
printit(1)
TurnArray2D_180(@feld(0,0), SizeOf(Byte), 5)
printit(2)
TurnArray2D_270(@feld(0,0), SizeOf(Byte), 5)
printit(3)
Input()
DataSection
fielddat:
Data.b 3, 3, 178, 4, 4
Data.b 3, 3, 178, 4, 4
Data.b 178, 178, 178, 178, 178
Data.b 6, 6, 178, 5, 5
Data.b 6, 6, 178, 5, 5
EndDataSection