Sprite räumlich darstellen.

Anfängerfragen zum Programmieren mit PureBasic.
stevie1401
Beiträge: 700
Registriert: 19.10.2014 15:51
Kontaktdaten:

Sprite räumlich darstellen.

Beitrag 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
Ich programmiere nur noch mit Linux.
Linux Mint 21.x
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Image räumlich darstellen.

Beitrag 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.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
stevie1401
Beiträge: 700
Registriert: 19.10.2014 15:51
Kontaktdaten:

Re: Image räumlich darstellen.

Beitrag 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.
Ich programmiere nur noch mit Linux.
Linux Mint 21.x
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Image räumlich darstellen.

Beitrag 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.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Image räumlich darstellen.

Beitrag 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
Zuletzt geändert von STARGÅTE am 24.04.2016 00:42, insgesamt 2-mal geändert.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
udg
Beiträge: 566
Registriert: 20.06.2013 23:27

Re: Image räumlich darstellen.

Beitrag 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
PB v5.43 LTS + v6.02 LTS | Windows 7 x86 + 11 x64 - Gforce RTX 4090 - AMD Ryzen 9 5900X 12-Core Processor 4.2 GHz - 64,0 GB RAM,
ASUSTEK TUF Gaming X570 Plus
ASUS ROG Thor-1200P Platinum (1200W, Aura Sync, OLED Display, 0dB-Cooling)
1x 1 TByte Samsung MZ-V7S500BW 970 EVO Plus 1 TB NVMe M.2 Internal SSD
1x 2 TByte Samsung MZ-V7S2T0BW 970 EVO Plus 2 TB NVMe M.2 Internal SSD
von BiSONTE!. Kauft Hardware gern bei ihm.
Monitor:
LG 38GL950G-B 95 (38 Zoll) Ultragear Curved 21: 9 UltraWide QHD IPS
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Image räumlich darstellen.

Beitrag 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")
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
stevie1401
Beiträge: 700
Registriert: 19.10.2014 15:51
Kontaktdaten:

Re: Image räumlich darstellen.

Beitrag von stevie1401 »

Besten Dank!
Ich programmiere nur noch mit Linux.
Linux Mint 21.x
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Re: Image räumlich darstellen.

Beitrag 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.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Image räumlich darstellen.

Beitrag 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)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Antworten