Seite 1 von 2

Sprite räumlich darstellen.

Verfasst: 21.04.2016 08:35
von stevie1401
Ich suche eine Routine, mit welcher ich Spielkarten räumlich darstellen kann, so als ob man etwas schräg auf einen Tisch schaut und dann räumlich die Karten liegen sieht.
Die Spielkarten habe ich in 2D und möchte die räumliche Ansicht "on the fly" umrechnen. Ist das mit Gadget3D machbar. Hat jemand eine Idee, wie man das machen könnte?

__________________________________________________
Thread-Titel angepasst
24.04.2016
RSBasic

Re: Image räumlich darstellen.

Verfasst: 21.04.2016 09:30
von RSBasic
Du kannst z.B. mit TransformSprite() deine Grafik verzerren bzw. verformen.
Hier im Forum gibt es einige Beispielcodes. Such am besten nach TransformSprite3D.
Ein Beispielcode: http://www.purebasic.fr/english/viewtop ... 66#p333066
Den Code musst du allerdings anpassen. Einfach alle 3D-Funktionen umbenennen (z.B. TransformSprite3D() -> TransformSprite()) und Start3D(), Stop3D(), InitSprite3D() usw. entfernen.

Re: Image räumlich darstellen.

Verfasst: 23.04.2016 08:24
von stevie1401
Danke für deinen Tip.
Leider komme ich mit TransformSprite() überhaupt nicht klar.
Bei mir kommen da nur "demolierte" Bilder raus, aber keine auf einem Tisch liegende Karte.
Ich verstehe einfach nicht welche Parameter ich da eingeben muss.

Re: Image räumlich darstellen.

Verfasst: 23.04.2016 11:45
von RSBasic
Dann zippe deinen Code inkl. Grafik und lad es irgendwo hoch. Leute, die sich damit auskennen, können versuchen, den von dir geschriebenen TransformSprite-Code zu verbessern.

Re: Image räumlich darstellen.

Verfasst: 23.04.2016 15:03
von STARGÅTE
Ich habe mal das alte (und auch falsche) Beispiel von mir überarbeitet, hier die neue Methode:

Code: Alles auswählen

Procedure HyperTransformSprite(Sprite.i, Width.f, Height.f, Depth.f, Roll.f, Yaw.f, Pitch.f, AlignX.f=0.5, AlignY.f=0.5)
   
   Protected CosZ.f = Cos(Radian(Roll)), CosY.f = Cos(Radian(Yaw)), CosX.f = Cos(Radian(Pitch))
   Protected SinZ.f = Sin(Radian(Roll)), SinY.f = Sin(Radian(Yaw)), SinX.f = Sin(Radian(Pitch))
   
   Protected A11.f =  CosY*CosZ,                A12.f = -CosY*SinZ,                A13.f =  SinY
   Protected A21.f =  SinX*SinY*CosZ+CosX*SinZ, A22.f = -SinX*SinY*SinZ+CosX*CosZ, A23.f = -SinX*CosY
   Protected A31.f = -CosX*SinY*CosZ+SinX*SinZ, A32.f =  CosX*SinY*SinZ+SinX*CosZ, A33.f =  CosX*CosY
   
   Protected U0.f = -AlignX*Width,  U1.f = (1-AlignX)*Width
   Protected V0.f = -AlignY*Height, V1.f = (1-AlignY)*Height
   
   Protected Z1.f = U0*A31 + V0*A32 + Depth
   Protected Y1.f = ( U0*A21 + V0*A22 ) * Depth / Z1
   Protected X1.f = ( U0*A11 + V0*A12 ) * Depth / Z1
   Protected Z2.f = U1*A31 + V0*A32 + Depth
   Protected Y2.f = ( U1*A21 + V0*A22 ) * Depth / Z2
   Protected X2.f = ( U1*A11 + V0*A12 ) * Depth / Z2
   Protected Z3.f = U1*A31 + V1*A32 + Depth
   Protected Y3.f = ( U1*A21 + V1*A22 ) * Depth / Z3
   Protected X3.f = ( U1*A11 + V1*A12 ) * Depth / Z3
   Protected Z4.f = U0*A31 + V1*A32 + Depth
   Protected Y4.f = ( U0*A21 + V1*A22 ) * Depth / Z4
   Protected X4.f = ( U0*A11 + V1*A12 ) * Depth / Z4
   
   TransformSprite(Sprite, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4)
   
EndProcedure



InitSprite()
InitNetwork()

UseJPEGImageDecoder()

Enumeration
   #Window
   #Sprite
EndEnumeration

OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

SpriteQuality(#PB_Sprite_BilinearFiltering)

CatchSprite(#Sprite, ReceiveHTTPMemory("http://data.unionbytes.de/convergence_by_rahll.jpg"))

Repeat
   
   Repeat
      
      Select WindowEvent()
         Case #PB_Event_CloseWindow
            End
         Case #Null
            Break
      EndSelect
      
   ForEver
   
   ClearScreen(0)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, ElapsedMilliseconds()/10, 0, 0)
   DisplaySprite(#Sprite, 200, 150)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, 0, Sin(ElapsedMilliseconds()/1000)*70, 0)
   DisplaySprite(#Sprite, 600, 150)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, 0, 0, Sin(ElapsedMilliseconds()/1000)*70)
   DisplaySprite(#Sprite, 200, 450)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, ElapsedMilliseconds()/10, 0, -40, 1.0, 0.0)
   DisplaySprite(#Sprite, 600, 450)
   
   FlipBuffers()
   
ForEver
Die Funktion heißt HyperTransformSprite()
Übergeben wird dort die Breite, Höhe und eine "fiktive" Tiefe (die die Verzerrung beeinflusst, hohe Werte sind weniger perspektivisch).
Danach kommen die Rotationsachsen mit Z, Y und X Winkel.

Natürlich sollte man bei der Funktion beachten, dass PureBasic nicht die "Rückseite" des Sprites darstellt, also Winkel außerhalb von 90° unsichtbar sind.

Edit: Code Update auf Rotationszentrum

Re: Image räumlich darstellen.

Verfasst: 23.04.2016 15:33
von udg
STARGÅTE hat geschrieben:Ich habe mal das alte (und auch falsche) Beispiel von mir überarbeitet, hier die neue Methode:

Code: Alles auswählen


CatchSprite(#Sprite, ReceiveHTTPMemory("http://data.unionbytes.de/convergence_by_rahll.jpg"))

PB v5.30 nimmt dat nisch an

Re: Image räumlich darstellen.

Verfasst: 23.04.2016 15:39
von RSBasic
Du brauchst 5.40.

\\Edit:
Nimm stattdessen:

Code: Alles auswählen

ReceiveHTTPFile("http://data.unionbytes.de/convergence_by_rahll.jpg", GetTemporaryDirectory() + "convergence_by_rahll.jpg")
LoadSprite(#Sprite, GetTemporaryDirectory() + "convergence_by_rahll.jpg")

Re: Image räumlich darstellen.

Verfasst: 23.04.2016 16:41
von stevie1401
Besten Dank!

Re: Image räumlich darstellen.

Verfasst: 23.04.2016 18:29
von TheCube
Schicke kleine Demo, besonders für sin()/Cos() "Verweigerer" wie mich.
Kommt direkt in die Schnipselsammlung.

Könnte man mit wenig Aufwand die Procedure HyperTransformSprite noch um
einen variablen Drehpunkt erweitern ? Aktuell sitzt der ja fest in der Bildmitte.

Re: Image räumlich darstellen.

Verfasst: 24.04.2016 00:23
von STARGÅTE
Hier noch die Variante mit variablem Drehpunkt (AlignX und AlignY am Ende der Parameter)
0.0 wäre dabei links bzw. oben und 1.0 wäre rechts bzw. unten.

Code: Alles auswählen

Procedure HyperTransformSprite(Sprite.i, Width.f, Height.f, Depth.f, Roll.f, Yaw.f, Pitch.f, AlignX.f=0.5, AlignY.f=0.5)
   
   Protected CosZ.f = Cos(Radian(Roll)), CosY.f = Cos(Radian(Yaw)), CosX.f = Cos(Radian(Pitch))
   Protected SinZ.f = Sin(Radian(Roll)), SinY.f = Sin(Radian(Yaw)), SinX.f = Sin(Radian(Pitch))
   
   Protected A11.f =  CosY*CosZ,                A12.f = -CosY*SinZ,                A13.f =  SinY
   Protected A21.f =  SinX*SinY*CosZ+CosX*SinZ, A22.f = -SinX*SinY*SinZ+CosX*CosZ, A23.f = -SinX*CosY
   Protected A31.f = -CosX*SinY*CosZ+SinX*SinZ, A32.f =  CosX*SinY*SinZ+SinX*CosZ, A33.f =  CosX*CosY
   
   Protected U0.f = -AlignX*Width,  U1.f = (1-AlignX)*Width
   Protected V0.f = -AlignY*Height, V1.f = (1-AlignY)*Height
   
   Protected Z1.f = U0*A31 + V0*A32 + Depth
   Protected Y1.f = ( U0*A21 + V0*A22 ) * Depth / Z1
   Protected X1.f = ( U0*A11 + V0*A12 ) * Depth / Z1
   Protected Z2.f = U1*A31 + V0*A32 + Depth
   Protected Y2.f = ( U1*A21 + V0*A22 ) * Depth / Z2
   Protected X2.f = ( U1*A11 + V0*A12 ) * Depth / Z2
   Protected Z3.f = U1*A31 + V1*A32 + Depth
   Protected Y3.f = ( U1*A21 + V1*A22 ) * Depth / Z3
   Protected X3.f = ( U1*A11 + V1*A12 ) * Depth / Z3
   Protected Z4.f = U0*A31 + V1*A32 + Depth
   Protected Y4.f = ( U0*A21 + V1*A22 ) * Depth / Z4
   Protected X4.f = ( U0*A11 + V1*A12 ) * Depth / Z4
   
   TransformSprite(Sprite, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4)
   
EndProcedure



InitSprite()
InitNetwork()

UseJPEGImageDecoder()

Enumeration
   #Window
   #Sprite
EndEnumeration

OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

SpriteQuality(#PB_Sprite_BilinearFiltering)

CatchSprite(#Sprite, ReceiveHTTPMemory("http://data.unionbytes.de/convergence_by_rahll.jpg"))

Repeat
   
   Repeat
      
      Select WindowEvent()
         Case #PB_Event_CloseWindow
            End
         Case #Null
            Break
      EndSelect
      
   ForEver
   
   ClearScreen(0)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, ElapsedMilliseconds()/10, 0, 0)
   DisplaySprite(#Sprite, 200, 150)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, 0, Sin(ElapsedMilliseconds()/1000)*70, 0)
   DisplaySprite(#Sprite, 600, 150)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, 0, 0, Sin(ElapsedMilliseconds()/1000)*70)
   DisplaySprite(#Sprite, 200, 450)
   
   HyperTransformSprite(#Sprite, 160, 100, 300, ElapsedMilliseconds()/10, 0, -40, 1.0, 0.0)
   DisplaySprite(#Sprite, 600, 450)
   
   FlipBuffers()
   
ForEver
PS: Wäre nett, wenn stevie1401 in seinem Threadtitel noch das Wort Sprite einfügt (da es ja hier um Sprites geht und nicht um Images)