Seite 1 von 1

2D Plane Deformation ?

Verfasst: 26.01.2016 18:16
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.

Re: 2D Plane Deformation ?

Verfasst: 26.01.2016 21:41
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)

Re: 2D Plane Deformation ?

Verfasst: 26.01.2016 23:51
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

Re: 2D Plane Deformation ?

Verfasst: 27.01.2016 00:55
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     

Re: 2D Plane Deformation ?

Verfasst: 27.01.2016 01:39
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: