komisches Problem mit Variable

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

5k41

Betreff: komisches Problem mit Variable

BeitragMi, Aug 16, 2006 10:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo!
Ich habe mir gestern meine eigene 2D Alpha funktion geschrieben ( ja ich weiss es gibt tausende, aber ich muss das Rad immer 10 mal neu erfinden, damit ich etwas wirklich verstehe) und zum Test hab ich mir eben dieses kleinen Programm geschrieben:
Code: [AUSKLAPPEN]

Graphics 400,300,32,2

img1 = CreateImage(100,100)
img2 = CreateImage(100,100)

alpha# = 0

SetBuffer ImageBuffer(img1)
Color 255,0,0
Rect 0,0,100,100

SetBuffer ImageBuffer(img2)
Color 0,255,0
Rect 0,0,100,100

SetBuffer BackBuffer()

While Not KeyDown(1)

 DrawImage      img1,0,0
 ;DrawImage      img2,50,50
 DrawImageAlpha img2,50,50,alpha
 
 Text 0,0,alpha
 
 If KeyDown(200) And alpha#<1 Then alpha#=alpha#+0.1
 If KeyDown(208) And alpha#>0 Then alpha#=alpha#-0.1
 
 Flip
 Cls
Wend
End

Function DrawImageAlpha(img,x,y,alpha#)

 LockBuffer ImageBuffer(img)
 LockBuffer BackBuffer()
 
 For u=0 To ImageWidth(img)-1
   For v=0 To ImageHeight(img)-1
   
    rgb  = ReadPixelFast(u,v,ImageBuffer(img))
   r    = aRed   (rgb)
    g    = aGreen (rgb)
    b    = aBlue  (rgb)
   
    rgb2 = ReadPixelFast(x+u,y+v,BackBuffer())
    r2   = aRed   (rgb2)
    g2   = aGreen (rgb2)
    b2   = aBlue  (rgb2)
   
    ar#  = r2+(r-r2) / (1 / alpha)
    ag#  = g2+(g-g2) / (1 / alpha)
    ab#  = b2+(b-b2) / (1 / alpha)
      
    WritePixelFast x+u,y+v,hColor(ar,ag,ab),BackBuffer()
      
   Next
 Next
   
 UnlockBuffer BackBuffer()
 UnlockBuffer ImageBuffer(img)

End Function

Function hColor(red,green,blue)
 Return red*$10000 + green*$100 + blue
End Function

Function aRed(hexcode)
 Return (hexcode And $FF0000)/$10000
End Function

Function aGreen(hexcode)
 Return (hexcode And $FF00)/$100
End Function

Function aBlue(hexcode)
 Return (hexcode And $FF)
End Function

nun ist aber das Problem garnicht die Funktion, sondern die Variable alpha aus der Hauptschleife. Geht man per Pfeiltaste hoch einen .1er schritt hoch und danach einen wieder runter funktioniert alles, geht man 2 hoch und wieder runter auch, aber geht man 3 hoch und wieder runter, so kommt statt 0.0 auf einmal 1.4e sonstewas und man kann noch einen schritt zu -.1 machen. Ich find den Fehler einfach nicht und hab nun irgendwie den Verdacht, dass es an Blitz liegt Confused

MfG und Vielen Dank schonmal im Vorraus
Projekte:
For a better World - Gesellschaftsspiel ( 100%)

User posted image
 

Dreamora

BeitragMi, Aug 16, 2006 11:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Weder noch
Es liegt an der Tatsache, dass Floats halt ihre genauigkeitsbeschränkungen haben. Deswegen sollte man auch nicht 0.1 oder 0.01 hoch gehen sondern immer 2er Potenzen bzw Summe von 2er Potenzen, denn die kann die CPU genau darstellen.

Das es erst geht, liegt daran dass BlitzPlus und Blitz3D das Problem in einem gewissen Rahmen abfangen. Man kann es selbst auch ein wenig beeinflussen, indem man wenn man mit Float arbeitet, es nicht dazu zwingt, total ungenau zu werden indem man keine unnutzen / und * einbaut:

Code: [AUSKLAPPEN]

ar#  = r2+(r-r2) / (1 / alpha)
ag#  = g2+(g-g2) / (1 / alpha)
ab#  = b2+(b-b2) / (1 / alpha)


zb kann man auch als
Code: [AUSKLAPPEN]

ar#  = r2+(r-r2) *alpha
ag#  = g2+(g-g2)*alpha
ab#  = b2+(b-b2)*alpha


schreiben, wodurch man nicht 2x ungenauigkeit erzeugt (denn 1/alpha gibt schon einen Rundungsfehler und etwas durch rundungsfehler gibt nen noch grösseren rundungsfehler)
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

BladeRunner

Moderator

BeitragMi, Aug 16, 2006 11:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Tut es, liegt an der Ungenauigkeit von Floats.
Was Du machen kannst ist auf <=0 zu prüfen ob noch ein Schritt möglich ist. Oder deine Variable auf Null zu setzen wenn sie <0 ist.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

5k41

BeitragMi, Aug 16, 2006 11:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Super! Danke für eure Hilfe hier nochmal der Code ( nun mit mehr als Doppelt so schneller DrawAlphaImage funktion)
Code: [AUSKLAPPEN]

Graphics 400,300,32,2

img1  = CreateImage(100,100)
img2  = CreateImage(100,100)

alpha = 0

SetBuffer ImageBuffer(img1)
Color 255,0,0
Rect 0,0,100,100

SetBuffer ImageBuffer(img2)
Color 0,255,0
Rect 0,0,100,100

SetBuffer BackBuffer()

While Not KeyDown(1)

 DrawImage      img1,0,0
 DrawImageAlphaFast img2,50,50,Float(alpha)/Float(10)
 
 Text 0,0,alpha
 
 If KeyDown(200) And alpha<10 Then alpha=alpha+1
 If KeyDown(208) And alpha>0 Then alpha=alpha-1
 
 Flip 0
 Cls
Wend
End

Function DrawImageAlpha(img,x,y,alpha#)

 LockBuffer ImageBuffer(img)
 LockBuffer BackBuffer()
 
 For u=0 To ImageWidth(img)-1
   For v=0 To ImageHeight(img)-1
   
    rgb  = ReadPixelFast(u,v,ImageBuffer(img))
   r    = aRed   (rgb)
    g    = aGreen (rgb)
    b    = aBlue  (rgb)
   
    rgb2 = ReadPixelFast(x+u,y+v,BackBuffer())
    r2   = aRed   (rgb2)
    g2   = aGreen (rgb2)
    b2   = aBlue  (rgb2)
   
    ar#  = r2+(r-r2) * alpha
    ag#  = g2+(g-g2) * alpha
    ab#  = b2+(b-b2) * alpha
      
    WritePixelFast x+u,y+v,hColor(ar,ag,ab),BackBuffer()
      
   Next
 Next
   
 UnlockBuffer BackBuffer()
 UnlockBuffer ImageBuffer(img)

End Function

Function DrawImageAlphaFast(img,x,y,alpha#)

 LockBuffer ImageBuffer(img)
 LockBuffer BackBuffer()
 
 For u=0 To ImageWidth(img)-1
   For v=0 To ImageHeight(img)-1
   
    rgb  = ReadPixelFast(u,v,ImageBuffer(img))
    rgb2 = ReadPixelFast(x+u,y+v,BackBuffer())
   
    ar   = (((rgb2 And $FF0000) / $10000) + (((rgb And $FF0000) / $10000) - ((rgb2 And $FF0000) / $10000)) * alpha)
    ag   = (((rgb2 And $FF00)   / $100)   + (((rgb And $FF00)   / $100)   - ((rgb2 And $FF00)   / $100))   * alpha)
    ab   = ((rgb2 And $FF)                + ((rgb And $FF)                - (rgb2 And $FF))                * alpha)
      
    WritePixelFast x+u,y+v,ar*$10000 + ag*$100 + ab,BackBuffer()
      
   Next
 Next
   
 UnlockBuffer BackBuffer()
 UnlockBuffer ImageBuffer(img)
 
End Function

Function hColor(red,green,blue)
 Return red*$10000 + green*$100 + blue
End Function

Function aRed(hexcode)
 Return (hexcode And $FF0000)/$10000
End Function

Function aGreen(hexcode)
 Return (hexcode And $FF00)/$100
End Function

Function aBlue(hexcode)
 Return (hexcode And $FF)
End Function
Projekte:
For a better World - Gesellschaftsspiel ( 100%)

User posted image

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group