2D Plane Deformation ?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
blastar
Beiträge: 25
Registriert: 10.06.2011 17:23

2D Plane Deformation ?

Beitrag von blastar »

Hallo,

bei der Suche nach Möglichkeiten Images zu manipulieren (Filter wie Blur, Sharp usw.) bin ich auf das Thema 'Plane Deformation' gestossen.
Das schaut interessant und eigentlich ganz einfach aus aber bei mir kommt immer nur Pixelmatsch raus! :(

plane-deformations-are-fun
deform

Ich vermute mal das liegt am unterschiedlichen Handling von SIN/COS/ATAN. :(
Kann mir da bitte jemand mit ein paar Zeilen in PB auf die Spünge helfen?

Danke.
Benutzeravatar
Macros
Beiträge: 1314
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: 2D Plane Deformation ?

Beitrag von Macros »

Ich hab dir mal einen kleinen Code zusammengeworfen.

Einfach ist es, solange du mit den Formeln experimentierst.
Komplizierter wird es, wenn du damit etwas bestimmtes erreichen willst ;)

Achtung, der Code ist so gut wie nicht optimiert, am besten den Debugger zum testen ausschalten.
Es stehen jedoch Tipps drinnen, wie du mehr Geschwindigkeit herausholen kannst.

Code: Alles auswählen

UseJPEGImageDecoder()
InitSprite()
InitNetwork()
InitKeyboard()

#xres=800
#yres=600
#targetfile="image.jpg"

OpenScreen(#xres,#yres,32,"Plane Deformation",#PB_Screen_SmartSynchronization,10)
StartDrawing(ScreenOutput())
DrawText(100,100,"Initializing",$ffff,0)
StopDrawing()
FlipBuffers()

; Irgendein Bild das wir verwenden, Bilder die an den Rändern ineinander
; übergehen machen sich gut. Hier ein (nicht ganz langweiliges) Schachbrett
ReceiveHTTPFile("https://www.filterforge.com/filters/2031.jpg",#targetfile)
LoadImage(1,#targetfile)
ResizeImage(1,512,512)

Dim Color.l(512,512)
; Wir lesen das Bild in ein Array, damit das Programm nicht endlos langsam ist
StartDrawing(ImageOutput(1))
For y=0 To 511
  For x=0 To 511
    Color(x,y)=Point(x,y)
  Next
Next
StopDrawing()


StartDrawing(ScreenOutput())
Box(0,0,1024,768)
StopDrawing()
FlipBuffers()

Repeat
  FlipBuffers()
  ExamineKeyboard()
  
  
  r.d+0.005
  StartDrawing(ScreenOutput())
  For y=0 To #yres-1
    For x=0 To #xres-1
      ; Mit leichter Modifikation aus dem zweiten Artikel übernommen
      ; Achtung, du fütterst Cos und Sin in Programmiersprachen mit Radians Werten
      ; Also 0 bis 2*#PI , die 360° entsprechen. D.h. deine Werte dürfen sich nicht schnell ändern
      u = x*Cos(2*r)*Sin(y/100)-y*Sin(2*r)
      v = y*Cos(2*r) + x*Sin(r*1.9)
      ; Hier kann viel an Geschwindigkeit gewonnen werden, sieh dir die mal Drawingbuffer Befehle an
      ; Und eine Look Up Table holt auch nochmal einiges raus.
      Plot(x,y,Color(u&511,v&511))
    Next
  Next
  StopDrawing()
  
  
  Until KeyboardPushed(#PB_Key_Escape)
DeleteFile(#targetfile)
Bild
blastar
Beiträge: 25
Registriert: 10.06.2011 17:23

Re: 2D Plane Deformation ?

Beitrag von blastar »

Vielen Dank für die schnelle und ausführliche Hilfe, es lebt! :D

Ich habe mir den Code mal auf ein Canvasgadget umgeschrieben und das Image ist local hinterlegt (das dem 'ReceiveHTTPFile' will irgendwie nicht aber ist auch nicht so wichtig). Weiterhin habe ich den Echtzeit-Loop durch 2 LUT's ersetzt die beim Programmstart gefuellt werden, im EventLoop wird nur noch die Texture verschoben... soweit so gut. Ich will beim Start einfach nur die wichtigsten LUTs zB fuer eine Lupe erzeugen und dann ueber eine Texture legen.

Jetzt wollte ich erstmal die Formeln abbilden wo das Ergebnis bekannt ist aber das klappt irgendwie nicht. :-(

u = x * cos(r * 2) - (y * sin(r * 2)) // 256
v = y * cos(r * 2) + (x * sin(r * 2)) // 256

Code: Alles auswählen

UseJPEGImageDecoder()

LoadImage(1,"2031.jpg")
ResizeImage(1,512,512)

Dim Color.l(512,512)
StartDrawing(ImageOutput(1))
  For y=0 To 511
    For x=0 To 511
      Color(x,y)=Point(x,y)
    Next
  Next
StopDrawing()
FreeImage(1)  


Dim LUTX.w(640,480)
Dim LUTY.w(640,480)

;---------------------------------
;LUT's fuellen
;---------------------------------

For y = 0 To 480-1
  For x = 0 To 640-1
    
    ;??????????????????????????
    
    r.f = 1
    LUTX(x,y) = x*Cos(2*r)*Sin(y/100)-y*Sin(2*r)
    LUTY(x,y) = y*Cos(2*r) + x*Sin(r*1.9)
    
  Next  
Next    

OpenWindow(0, 0, 0, 640, 480, "PlaneDeform", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 640, 480)

Repeat
  Event = WaitWindowEvent(1000/10)
  
  ;---------------------------------
  ; Texture verschieben
  ;---------------------------------
  
  addx + 1
  addy + 1
  
  ;---------------------------------
  ; u/v aus LUT's holen und zeichnen
  ;---------------------------------
  
  StartDrawing(CanvasOutput(0))
    For y=0 To 480-1
      For x=0 To 640-1
        u = LUTX(x,y)
        v = LUTY(x,y)
        Plot(x,y,Color((u+addx)&511,(v+addy)&511))
      Next
    Next
  StopDrawing()
  
Until Event = #PB_Event_CloseWindow
Zuletzt geändert von blastar am 27.01.2016 02:16, insgesamt 1-mal geändert.
Benutzeravatar
Macros
Beiträge: 1314
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: 2D Plane Deformation ?

Beitrag von Macros »

Das sieht schon super aus, und viel flotter :allright:

Wegen dem ReceiveHttpFile solltest du vielleicht dein PureBasic updaten.
- Hinzugefügt: HTTPS und einfach Auth. Unterstützung für ReceiveHTTPFile() und GetHTTPHeaders()
Dir hat die dynamische Berechnung von r gefehlt.

Sonst hat der Taschenrechner wohl ein seltsames Koordinatensystem hat bei dem 0 in der Mitte des Bildschirms liegt.
Die Skalierung ist auch etwas anders, daher das /400 beim Radius.
Ich hab das unten angepasst. Die auskommentierten Zeilen sind das Beispiel über dem von dir gewählten. Viel Spaß :)

Code: Alles auswählen

;---------------------------------
;LUT's fuellen
;---------------------------------

For y = 0 To 480-1
  For x = 0 To 640-1
   
    cx.d=(x-320)
    cy.d=(y-240)
    r.d = Sqr(cx*cx+ cy*cy)/400
    a.d=ATan2(cx,cy)
    LUTX(x,y) =cx* Cos(r * 2) - (cy * Sin(r * 2))
    LUTY(x,y)=cy * Cos(r * 2) + (cx * Sin(r * 2))
    
     
    ;     LUTX(x,y) =cx *80 / Abs(cy+0.001); 
    ;     LUTY(x,y) =512 /  Abs(cy+0.001)*10
    
  Next  
Next     
Bild
blastar
Beiträge: 25
Registriert: 10.06.2011 17:23

Re: 2D Plane Deformation ?

Beitrag von blastar »

Daaanke, funktioniert bestens! :bounce:

Aktuell nutze ich 5.31 da ich einige größere Projekte damit habe und bei 5.4x auf einige Problemchen gestoßen bin. Habe zwar parallel auch immer die aktuellste Version installiert (sowie auch 4.61) aber nutze aus Gewohnheit fast immer nur 5.31.

Danke! :allright:
Antworten