Seite 1 von 1

Floating Point-Artefakt

Verfasst: 11.06.2010 17:17
von TomDest
Hallo Forum,

ich habe Win7 und gerade frisch PB 4.50.

Folgendes Programm zeigt komische Artefakte:

Code: Alles auswählen

EnableExplicit
#Anzahl=8
#Groesse=200
Define.l Lauf, EventID
Global i
Define ZufallX.f, ZufallY.f, ZufallZ.f, Dummy.f
Global Dim x.f(#Anzahl)
Global Dim y.f(#Anzahl)
Global Dim z.f(#Anzahl)
Global Dim xn.f(#Anzahl)
Global Dim yn.f(#Anzahl)
Global Dim zn.f(#Anzahl)
Global Hoehe_halb.f
Global Breite_halb.f
Hoehe_halb.f=768/2
Breite_halb.f=1024/2
Global MitteX.f
Global MitteY.f
MitteX.f=Breite_halb
MitteY.f=Hoehe_halb


Procedure Zeichnen()
StartDrawing(WindowOutput(0))
FrontColor(RGB(0,0,0))
BackColor(RGB(255,255,255))
LineXY (x(1)+MitteX,y(1)+MitteY,x(2)+MitteX,y(2)+MitteY)
LineXY (x(2)+MitteX,y(2)+MitteY,x(3)+MitteX,y(3)+MitteY)
LineXY (x(3)+MitteX,y(3)+MitteY,x(4)+MitteX,y(4)+MitteY)
LineXY (x(4)+MitteX,y(4)+MitteY,x(1)+MitteX,y(1)+MitteY)
LineXY (x(1)+MitteX,y(1)+MitteY,x(5)+MitteX,y(5)+MitteY)
LineXY (x(5)+MitteX,y(5)+MitteY,x(6)+MitteX,y(6)+MitteY)
LineXY (x(6)+MitteX,y(6)+MitteY,x(7)+MitteX,y(7)+MitteY)
LineXY (x(7)+MitteX,y(7)+MitteY,x(8)+MitteX,y(8)+MitteY)
LineXY (x(8)+MitteX,y(8)+MitteY,x(5)+MitteX,y(5)+MitteY)
LineXY (x(2)+MitteX,y(2)+MitteY,x(6)+MitteX,y(6)+MitteY)
LineXY (x(3)+MitteX,y(3)+MitteY,x(7)+MitteX,y(7)+MitteY)
LineXY (x(4)+MitteX,y(4)+MitteY,x(8)+MitteX,y(8)+MitteY)
StopDrawing()
EndProcedure

Procedure Loeschen()
;ClearScreen(255,255,255) 
StartDrawing(WindowOutput(0))
Box(0,0,Breite_halb*2,Hoehe_halb*2,RGB(255,255,255))
StopDrawing()
EndProcedure

Procedure XDrehung(Winkel1.f)
 Define.f Winkel, Cosinus, Sinus
 Winkel.f = Winkel1 * 2 * #PI / 360
 Cosinus.f = Cos(Winkel)
 Sinus.f = Sin(Winkel)
  For i = 1 To #Anzahl
   yn(i) = y(i) * Cosinus + z(i) * Sinus
   zn(i) = -y(i) * Sinus + z(i) * Cosinus
  Next i
  For i = 1 To #Anzahl
   y(i) = yn(i)
   z(i) = zn(i)
  Next i
EndProcedure

Procedure YDrehung(Winkel1.f)
 Define.f Winkel, Cosinus, Sinus
 Winkel.f = Winkel1 * 2 * #PI / 360
 Cosinus.f = Cos(Winkel)
 Sinus.f = Sin(Winkel)
  For i = 1 To #Anzahl
   xn(i) = x(i) * Cosinus + z(i) * Sinus
   zn(i) = -x(i) * Sinus + z(i) * Cosinus
  Next i
  For i = 1 To #Anzahl
   x(i) = xn(i)
   z(i) = zn(i)
  Next i
EndProcedure

Procedure ZDrehung(Winkel1.f)
  Define.f Winkel, Cosinus, Sinus
  Winkel.f = Winkel1 * 2 * #PI / 360
 Cosinus.f = Cos(Winkel)
 ;PrintN("winkel= "+Str(Winkel))
 Sinus.f = Sin(Winkel)
  For i = 1 To #Anzahl
   xn(i) = x(i) * Cosinus + y(i) * Sinus
   ;PrintN("xn(i)="+Str(xn(i)))
   yn(i) = -x(i) * Sinus + y(i) * Cosinus
  Next i
  For i = 1 To #Anzahl
   x(i) = xn(i)
   y(i) = yn(i)
  Next i
EndProcedure




OpenWindow(0, 0, 0, Breite_halb*2, Hoehe_halb*2,"Drehung",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)


Restore Geometriedaten
For Lauf=1 To #Anzahl
 Read Dummy 
 x(Lauf)=Dummy*#Groesse
 ;Debug "Dummy="+StrF(Dummy)+" Variable="+StrF(x(Lauf)) 
Next Lauf
For Lauf=1 To #Anzahl
 Read Dummy 
 y(Lauf)=Dummy*#Groesse
 ;Debug "Dummy="+StrF(Dummy)+" Variable="+StrF(y(Lauf))
Next Lauf
For Lauf=1 To #Anzahl
 Read Dummy 
 z(Lauf)=Dummy*#Groesse
 ;Debug "Dummy="+StrF(Dummy)+" Variable="+StrF(z(Lauf))
Next Lauf 


;End

Zeichnen()


 Repeat
  EventID = WindowEvent()
 Loeschen()
 XDrehung(1)
 YDrehung(1)
 ZDrehung(1)
 Zeichnen()
 ;DoEvents()
 Delay(15)
 
Until EventID = #PB_Event_CloseWindow ; If the user has pressed on the close button

End


DataSection:


Geometriedaten:
Data.i -1,-1,1,1,-1,-1,1,1
Data.i 1,1,1,1,-1,-1,-1,-1
Data.i -1,1,1,-1,-1,1,1,-1

EndDataSection
So funktioniert das Programm - im Original stand da aber in der DataSection hinter jedem Data ein ".f", also "Data.f ...". Damit ging es nicht - kostete mich > 30 min!
"Entkommentiert" man die Debug-Anweisungen in den Einleseschleifen, sieht man, dass statt der kleinen Werte (-1 oder 1) sehr große Werte eingelesen werden ("Dummy=-1082130432.000000 Variable=-216426086400.000000"). Damit ist der 3D-Würfel natürlich zu groß und man sieht nichts mehr.

Woher kommt dieses Verhalten, also warum füllt er die Variablen falsch?

Viele Grüße,

Tom

Re: Floating Point-Artefakt

Verfasst: 11.06.2010 17:25
von STARGÅTE
Da du kein Typenbie Read angegeben hast !

Wenn du daten vom Typ .f hast, dann musst du das auch beim Read angeben, auch wenn die variable dahinter .f ist.

Code: Alles auswählen

Read.f Dummy 
es geht mit .i, weil .i der StandardTyp ist ... du kannst aber auch wieder .f nehmen, wenn du dieÄnderungen machst.

Re: Floating Point-Artefakt

Verfasst: 11.06.2010 17:30
von Kurzer
Read benötigt einen Datentyp, damit der korrekte Wert gelesen wird.

Wenn Du Read.f schreibst, geht alles wie geschmiert.

Standardmäßig (also ohne Angabe eines Typs) geht Read davon aus den "Standard Datentyen" einzulesen. Und der ist, glaube ich, integer solange man ihn nicht mittels Define verändert.

Somit versucht Read also Deine Floatwerte mit einem Integer-Zugriff auszulesen und das gibt Murks.

Edit: Mist, zu langsam. :|

Re: Floating Point-Artefakt

Verfasst: 11.06.2010 17:38
von PureLust
Wie Stargate schon sagte, solltest Du die Typen einheitlich halten - also entweder Variablen UND Data-Section als Integer, oder eben beides als Float.

Aber zu dem eigentlichen Problem:
TomDest hat geschrieben:"Entkommentiert" man die Debug-Anweisungen in den Einleseschleifen, sieht man, dass statt der kleinen Werte (-1 oder 1) sehr große Werte eingelesen werden ("Dummy=-1082130432.000000 Variable=-216426086400.000000"). Damit ist der 3D-Würfel natürlich zu groß und man sieht nichts mehr.
Also auf meinem aktuellen System (WinXP - 32Bit) funktioniert Dein Beispiel einwandfrei.
Der Grund, warum es bei Dir nicht funktioniert ist vermutlich, das Du ein 64Bit Beriebsystem hast - richtig?
Denn auf einem 32Bit Betriebsystem ist sowohl der Interegr-Typ als auch der Float-Typ 4Byte groß.
Auf einem 64Bit System ist der Integer-Typ jedoch 8Bytes groß - dies kann dann zu Problemen führen wenn Du wie oben beschrieben einen Typenmix machst.

Versuche mal die Data-Sektion wieder in Data.f und die oben stehenden Reads in Read.f zu ändern - dies sollte dann auch bei Dir funktionieren.

[Edit] Ahh ... habe gerade festgestellt WANN Du die zu großen Werte bekommst - die bekommst Du also nicht in dem von Dir geposteten Beispiel, sondern die hattest Du bekommen als die Data-Sektion noch ".f" hatte - also vergiss das mit dem 64Bit-System. ;)
Der Fehler war also, dass die Werte "-1" und "1" im Float-Format abgelegt waren, Du jedoch per Integer-Read darauf zugegriffen hast - somit sind die ausgelesenen Werte natürlich falsch.
(Hmmm ... hätte eigentlich gedacht, dass der Debugger bei einem falschen Data-Typ meckert. :roll: )
Aber sei's drum ... wenn Du den Data-Typ beachtest, gibt's keine Probleme. :allright:

Greetz, PL.

Re: Floating Point-Artefakt

Verfasst: 11.06.2010 17:45
von TomDest
Gott, seid ihr schnell... :o

Danke für die Antworten!

Ergo wieder Newbie-Fehler bzgl. Read + Suffix, sorry... :roll:

Bzgl. Windows: Nope, das ist 32-bit Win 7 HP...

Viele Grüße,

Tom