Heya everyone :D Very long time no see !
Sorry for not being present all that time, I already explained the situation to shockwave so I won't tell all the story here but I just don't code as much as I would.
Anyway, here is a little snippet I coded yesterday, I thought it could interest some of you :) Thanks to duke4e from freebasic forums, hellfire and Jim from well.. here ;) for the optimisation :)
A screenshot :
(http://narky00.free.fr/Capture-waves.png)
The code :
Screenres 320,240,32
Const ZOOM_FACTOR = .003
Type WaveT
As Single x,y
As Single Freq
End Type
#include "fbgfx.bi"
Const _reduct = 1/(255*255)
Const _255 = 1/255
Dim Shared As Single t
Dim Shared As WaveT Wave(2)
Dim Shared As Uinteger Pal(255)
Dim Shared As Any Ptr Back
Dim Shared As Uinteger Ptr buffer
Dim Shared As Integer Ptr pixel
buffer = Screenptr()
Wave(0).Freq = .052
Wave(1).Freq = .08
Wave(2).Freq = .086
Back = Imagecreate(320,240)
'From vdecampo post
pixel = back+SizeOf(FB.IMAGE) 'Skip over image header
Bload "blue_sunset.bmp",Back
Sub HandleWaves()
Static As Integer cR,cG,cB,ii,ii2,ii3,jj,rr,gg,bb
Static As Uinteger col,p
For i As Integer = 0 To 319
ii = (Wave(0).x-i)*(Wave(0).x-i)
ii2 = (Wave(1).x-i)*(Wave(1).x-i)
ii3 = (Wave(2).x-i)*(Wave(2).x-i)
For j As Integer = 0 To 239
jj = Wave(0).y-j
cR = 128+127*Cos(ZOOM_FACTOR*(ii + jj*jj)*Wave(0).Freq+t)
jj = Wave(1).y-j
cG = 128+127*Cos(ZOOM_FACTOR*(ii2 + jj*jj)*Wave(1).Freq+t)
jj = Wave(2).y-j
cB = 128+127*Cos(ZOOM_FACTOR*(ii3 + jj*jj)*Wave(2).Freq+t)
Cr = (Cr+Cg+Cb+(255-Cr)*.5)/3
'p = Point(Abs(i-Cr*.5),Abs(j-Cr*.5),Back)
'vdecampo
p = pixel[Cint(Abs(j-Cr*.5f)) * 320 + Cint(Abs(i-Cr*.5f))]
bb = Cr * (p And 255) * _255
gg = Cr * ((p Shr 8) And 255) * _255
rr = Cr * ((p Shr 16) And 255) * _255
buffer[i + 320 * j] = Rgb(rr,gg,bb)
Next
Next
End Sub
Do
Screenlock : Cls
Wave(0).x = 100-80*Cos(t*.1)
Wave(0).y = 180-120*Sin(t*.5)
Wave(1).x = 300+50*Cos(t*.4)
Wave(1).y = 200+40*Sin(t*.2)
Wave(2).x = 50+10*Cos(t*.3)
Wave(2).y = 60+130*Sin(t*.2)
HandleWaves()
t+=.1
Screenunlock : Sleep 1,1
Loop Until Multikey(&h01)
Imagedestroy(Back)
The background image :
(http://freefile.kristopherw.us/uploads/hezad/blue_sunset.bmp)
(save as "blue_sunset.bmp" in the same folder as the source file. You can use any 320x240 bmp file :) )
Thats pretty excellent actually Hezad, if I hadn't seen the bitmap then I would never have guessed what the source picture looked like :)
Oh, and it's totally great to see you again!
Exe attached.. (it still needs the image).
I saw this on the FB forum. Cool stuff.
Thanks a lot :)
Shockwave >and thanks for the exe ;)
Very pretty! Glad to see you back on the scene too. :)
Jim
welldone Hezad :)
thanks :buddies:
Nice to see you again, mate!
Very good work. Keep it up!
Nice one, Hezad!
For each pixel you're calculating the distances to some center-points.
Using multiple square-roots per pixel is quite costly, though.
If you really need floating-point precision you can take advantage of the fact that the change in distance is very small when traversing from one pixel to the next.
So instead of calculating the "complete" square-root, you could use the previous pixel's distance as an estimation and use eg the newton-method (http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots) to approximate the current pixel's distance.
Instead of this...
For y = 0 To 239
For x = 0 To 319
val = x1*x1 + y1*y1
dist = sqr(val)
...you could try this:
For y = 0 To 239
' calculate a correct value for the first pixel
val= x1*x1 + y1*y1
approx= 1.0 / sqr(val)
For x = 0 To 319
val = x1*x1 + y1*y1
' estimate the next pixel from the previous approximation
approx= approx*0.5 * (3.0 - val*approx*approx)
' this is required to make it stable
if approx < 0.0 then approx= 0.0
val*= approx
Cool idea!
I'd be surprised if the fx looked substantially different if the sqrt(x) were removed completely and replaced with a scale factor, eg. x * 0.007 (guess x in range 0-160, y in range 0-120, so x^2+y^2 approx= 22500 and sqrt(x^2+y^2) approx = 150 implies scale factor of 150/22500=1/150=0.00666.
Jim
thanks again mates :)
hellfire > One more excellent advice, thanks :) Since Jim's idea (I'll speak about it :) ) suppress the sqrt, I won't use it anymore but it'll be definitely useful for next programs !
Jim > excellent ! the result is almost (if not exactly) the same and no square root to calculate :) Thanks !
(updated code on first post)
This looks cool, but I cant figure out how it works. Would someone care to explain?
thanks spitfire :)
Well, it's a combination of a black and white plasma and a background image. The image is drawn on screen but for each point, the program checks the plasma color. It uses the color value to choose a point on the background image : the whiter the plasma is, the farther the program will look for a pixel color on the background image.
Sorry for the poor vocabulary :S
Thats a really nice explanation :)
Yes thats a good explanation thanks. But what about the darker areas at the bottom, since theres no black in the image. Or do you just mix black with the texture colour when the plasma is below a certain threshold?
In fact, the plasma is not only used to calculate the "displacement" but there's also kind of an alpha blending between the plasma and the background image. White => totally transparent (and max displacement) / Black => no transparency (and min displacement) :)
very good and I like that.....You could have rainbow colours 8)
Welldone ;D
thanks :cheers: