TFormImage Beispiel

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

Holzchopf

Meisterpacker

Betreff: TFormImage Beispiel

BeitragDo, Mai 28, 2009 20:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Wo wir schon grad dabei sind, die Festplatte nach Codes zu durchsuchen... Rolling Eyes (vor wenigen Wochen entstanden)

Ich hab mir mal erlaubt (ich weiss, ich weiss, sowas gibts hier schon) ein Beispiel + Erklärung zum Befehl TFormImage zu schreiben und möchte das auch präsentieren =) Ich denke, der Code ist ausführlich genug kommentiert.
Code: [AUSKLAPPEN]
; TFormImage Beispiel von Holzchopf für alle.
;------------------
; Das Ganze basiert übrigens auf der Erkenntnis, dass man die Transformationsmatrix
;
;     | a#  c# |
; M = |        |
;     | b#  d# |
;
; (mit Phantasie) auch als zwei Vektoren
;
;     | a# |
; u = |    |
;     | b# |
;
;     | c# |
; v = |    |
;     | d# |
;
; betrachten kann. Wobei u den Vektor für die neue "X-Achse" und v
;  denjenigen für die neue, transformierte "Y-Achse" darstellt.
;------------------

; Und ab gehts:
Graphics 800,600,0,2         ; Erstmal schick ein Fenster mit
SetBuffer BackBuffer()         ;  Doublebuffering erstellen.
Global TIMER=CreateTimer(60)   ; Framebegrenzung? NEIN! CPU-Kühlung.
TFormFilter False            ; Auf True setzen für HQ-Bildchen (langsam).

; Das Bild xy.png gibts hier http://www.blitzforum.de/upload/file.php?id=4734
Local imgFile$="xy.png"         ; Das Demo-Bild (ggf mit Pfad)
Local imgSrc=LoadImage(imgFile)   ;  als Ursprungsbild laden.
; Falls das Bild nicht geladen werden konnte, wird prompt Meldung erstattet:
If Not imgSrc RuntimeError imgFile +" konnte nicht geladen werden."
Local imgW=ImageWidth(imgSrc)   ; Breite
Local imgH=ImageHeight(imgSrc)   ;  und Höhe des Ursprungbilds.
Local img                  ; Das temporäre Bild, das transformiert wird.

Global Demo=0      ; Die abzuspielende Demo
Global DemoTxt$[2]   ;  (sogar mit Zusatztexten).
Global phi         ; Phi sei unser Winkel, der das ganze in Bewegung hält
Global u#[1]      ;  und u unser Vektor der transformierten X-Achse
Global v#[1]      ;  und v dasselbe für die Y-Achse.

; Hauptschleife:
While Not KeyDown(1)
   Demo=Demo+KeyHit(205)-KeyHit(203)
   
   TFormDemo   ; Eine kleine Demo, was TFormImage denn so alles kann.

   ; Mit den Demowerten wird nun unser...
   img = CopyImage( imgSrc )            ; ...(kopiertes)...
   TFormImage img, u[0], u[1], v[0], v[1]   ; ... Bild transformiert.
;*****
; TFormImage -   1.Parameter: Bild
;            2.Parameter: x-Komponente der transf. X-Achse
;            3.Parameter: y-Komponente der transf. X-Achse
;            4.Parameter: x-Komponente der transf. Y-Achse
;            5.Parameter: y-Komponente der transf. Y-Achse
;*****

   ; Noch ein paar Textausgaben, weil Bilder allein nicht alles sagen.
   Cls
   Color 0,255,0
   Text 0,0,"Sequenz "+Demo+":  "+DemoTxt[0]
   Text 0,16,"Transformationsmatrix:"
   Text 10,32,DemoTxt[1]
   Text 10,48,DemoTxt[2]
   Text 0,64,"(Effektivwerte:)"
   Text 10,80,"| " +LSet(u[0],6)+"  "+LSet(v[0],6) +" |"
   Text 10,96,"| " +LSet(u[1],6)+"  "+LSet(v[1],6) +" |"
   Text 0,585,"Nächste Demosequenz mit Pfeil-nach-links-Taste, vorherige mit Pfeil-nach-rechts-Taste..."
   
   ; Das transformierte Bild will natürlich gezeichnet werden.
   DrawImage img,400,300
   
   ; Und die Vektoren der transformierten Achsen schmeissen wir noch hinterher.
   Color 255,0,0
   Text 400+u[0]*imgW, 300+u[1]*imgW, "[ "+LSet(u[0],5)+", "+LSet(u[1],5)+" ]", 1, 1
   Text 400+v[0]*imgH, 300+v[1]*imgH, "[ "+LSet(v[0],5)+", "+LSet(v[1],5)+" ]", 1, 1
   
   Flip 0            ; Backbuffer zeichnen,
   WaitTimer TIMER      ; Der Timer hält die CPU-Last niedrig
   FreeImage img      ;  und das Löschen der Bildkopie den Ram.
Wend
End

; Demo-Funktion
Function TFormDemo()
   phi=phi+1   ; Wie gesagt, Phi hält alles in Bewegung.

   ; Aktive Demo abspielen.
   Select Demo
   Case 0      ; Keine Transformation
      u[0]=1   v[0]=0
      u[1]=0   v[1]=1
      DemoTxt[0]="Durch eine Identitätsmatrix wird das Bild nicht Transformiert."
      DemoTxt[1]="| 1  0 |"
      DemoTxt[2]="| 0  1 |"
   Case 1      ; Strecken einer Achse
      u[0]=2   v[0]=0
      u[1]=0   v[1]=1
      DemoTxt[0]="Diese Matrix streckt die X-Achse."
      DemoTxt[1]="| 2  0 |"
      DemoTxt[2]="| 0  1 |"
   Case 2      ; Spiegeln
      u[0]=0   v[0]=1
      u[1]=1   v[1]=0
      DemoTxt[0]="Diese Matrix spiegelt das Bild an der x=y Geraden."
      DemoTxt[1]="| 0  1 |"
      DemoTxt[2]="| 1  0 |"
   Case 3      ; Zerren
      u[0]=1      v[0]=0
      u[1]=-.5   v[1]=1
      DemoTxt[0]="Jetzt wirds interessant, unsere X-Achse wird in der Richtung gedreht..."
      DemoTxt[1]="| 1    0 |"
      DemoTxt[2]="| -.5  1 |"
   Case 4      ; ISO
      u[0]=1      v[0]=1
      u[1]=-.5   v[1]=0.5
      DemoTxt[0]="... und durch die Drehung der Y-Achse haben wir schon puren ISO-Fun."
      DemoTxt[1]="| 1  -0.5 |"
      DemoTxt[2]="| 1   0.5 |"
   Case 5      ; Rotation um Z
      u[0]=Cos(phi)   v[0]=Sin(phi)
      u[1]=-Sin(phi)   v[1]=Cos(phi)
      DemoTxt[0]="Für die schnellen PCs: Rotation (um die Z-Achse)."
      DemoTxt[1]="| cos(x)   sin(x) |"
      DemoTxt[2]="| -sin(x)  cos(x) |"
   Case 6      ; Rotation um Y (schief)
      u[0]=Cos(phi)   v[0]=1
      u[1]=-Cos(phi)   v[1]=2
      DemoTxt[0]="Für die schnellen PCs: Rotation um die schiefe Y-Achse."
      DemoTxt[1]="| cos(x)   1 |"
      DemoTxt[2]="| -cos(x)  2 |"
   Case 7      ; ISO-Rotation
      u[0]=Cos(phi)      v[0]=Sin(phi)
      u[1]=-Sin(phi)*.5   v[1]=Cos(phi)*0.5
      DemoTxt[0]="Für die schnellen PCs: Rotation (um die Z-Achse) in der ISO-Ansicht."
      DemoTxt[1]="| cos(x)       sin(x)     |"
      DemoTxt[2]="| -sin(x) *.5  cos(x) *.5 |"
   Default
      Demo=0
   End Select
End Function


xy.png aus dem Beispiel:
user posted image

Und so wirds aussehen:
user posted image

viel Spass damit! BB2D ist zwar schon ziemlich ausgestorben, aber vielleicht kommts jemandem nocht nicht zu spät =)

mfG
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

Noobody

BeitragDo, Mai 28, 2009 21:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schönes Beispiel für einen der unterschätztesten Befehle von Blitz Razz

Enziger Schönheitsfehler ist, dass A, B, C und D in der Matrix andersrum angeordnet sind Code: [AUSKLAPPEN]
     | a#  b# |
 M = |        |
     | c#  d# |

Die Vektoren des Koordinatensystems sind nämlich Zeilenweise und nicht Spaltenweise in der Matrix enthalten. Spielt aber schlussendlich für die Verwendung von TFormImage keine Rolle.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

Holzchopf

Meisterpacker

BeitragDo, Mai 28, 2009 22:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm und ich habs extra vorm hochladen überall geändert, weil wirs im Matheunterricht eben grad genau so gelernt haben... Confused Ich weiss nicht, wie das PC-Architekturmässig aussieht, gut möglich, dass da Matrizen die Vektoren zeilenweise enthalten. Aber ums Mathematisch nachvollziehbar zu halten, lass ich es in der spaltenweisen darstellung (weils ja schlussendlich tatsächlich keine Rolle spielt, wies gehandhabt wird - solange die Ergebnisse stimmen)

Edit:
Oh, oder hast du dein wissen einfach aus der Onlinehilfe? Rolling Eyes Wenn ja, dann werd ich in die Wege leiten, dass es dort geändert wird (ich bin naiv und der Meinung, dass das absolut den Regeln der Mathematik zu folgen hat Wink ). Wenn nicht: Könntest du mir die Quelle nennen?

Noobody

BeitragFr, Mai 29, 2009 6:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hatte mein Wissen aus einem Buch über Matrizenrechnung, aber scheinbar hatte ich das falsch in Erinnerung - die Vektoren sind, wie du gesagt hast, spaltenweise drin (ich hab sogar extra nochmals nachgeschlagen Razz ).

Ich bin nun aber etwas verwirrt, da dieser Code dann eigentlich gar nicht funktionieren dürfte, da ich hier die Vektoren Zeilenweise auslese Confused Ändere ich das ab in spaltenweise, so liefert die Funktion sogar falsche Ergebnisse.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

Xaymar

ehemals "Cgamer"

BeitragFr, Mai 29, 2009 14:22
Antworten mit Zitat
Benutzer-Profile anzeigen
@Noobody:
Die B3D Matrix ist 3x4 groß, du änderst also nicht
Zitat:
------
###
###
###

zu
Zitat:
|##
|##
|##
|##


sondern
Zitat:
|##
|##
|##
|##
(Edit: sollte nicht |### sein)
zu
Zitat:
------
###
###
###


d.h. X und Y sind bei getmatelement vertauscht.


@Holzchopf: ich habs vorher nie kapiert wie tformimage funzt, nu weiß ich es, thx:)
Warbseite
  • Zuletzt bearbeitet von Xaymar am Fr, Mai 29, 2009 16:48, insgesamt einmal bearbeitet

Holzchopf

Meisterpacker

BeitragFr, Mai 29, 2009 15:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab mich leider grad in nem anderen Thread verloren, drum antworte ich "zu spät" =)
Cgamer hat recht (mit dem vertauschten x und y) und ich möchte noch kurz meine Überlegungen nachliefern:

user posted image
Zuerst wird die linke Multiplikation erläutert, welche mMn die effiziente und somit richtige ist:
Das gelbe ist die EntityMatrix (auf die man mit GetMatElement zugreift), sie weisst lediglich eine Verschiebung auf (4. Spalte).
Das Lilane ist die Matrix des Tetraeders, zusammengesetzt aus den 4 Spaltenvektoren der Eckpunkte, die allesamt um (das orangene) Element erweitert wurden, welches dafür sorgt, dass der Ortsvektor des Eckpunktes auch auf Transformationen reagiert.
Das grüne ist das ergebnis der Matrizenmultiplikation, die hier grad schön die neuen Spaltenvektoren des Transformierten Meshs ausspucken.

Gucken wir uns die rechte Multiplikation an:
Das gelbe ist wieder die Transf.-Matrix, das lilane der Mesh und das grüne das Ergebnis der Multiplikation.
Hier sieht man jedoch schön, dass die neuen Spaltenvektoren nicht 1:1 die neuen Koordinaten darstellen. Zu den Komponenten der Vektoren müssten jeweils noch die Elemente A41 (für X) A42 (für Y) und A43 (für Z) addiert werden, was zusätzliche Operationen bedeutet und somit - denke ich - für die Technik einfach zu ineffizient ist.

Also ich glaube, der Hilfeeintrag zu GetMatElement vertauscht einfach Zeilen und Spalten - dann ist nämlich alles wieder beim alten, auch bei deinem Code.

mfG
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group