Brownian motion.

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
dodicat
Posts: 6365
Joined: Jan 10, 2006 20:30
Location: Scotland

Brownian motion.

Postby dodicat » Nov 18, 2019 22:40

Very quiet day on the forum today.
This is slightly less exciting than watching paint dry.

Code: Select all


Type ball
   x As Single    'position x component
   y As Single    'position y component
   dx As Single   'velocity x component
   dy As Single   'velocity y component
   col As Ulong   'colour
    As Long r,m    'radius, mass
End Type

dim shared as any ptr i

Sub MoveAndDraw( b() As ball,Byref e As Single,f As Single)'get energy also
    static as long counter,flag
    counter+=1
    if counter>50 then flag=1:counter=50 'allow time for balls to seperate
    For n As Long=Lbound(b) To Ubound(b)
        b(n).x+=b(n).dx*f:b(n).y+=b(n).dy*f
       if flag then Circle(b(n).x,b(n).y),b(n).r,b(n).col,,,,f
        e+=(.5*b(n).m*(b(n).dx*b(n).dx + b(n).dy*b(n).dy))
    Next n
    e*=f
    Draw String(b(0).x-16,b(0).y-8),"<-->",Rgb(200,0,0)
   if flag then pset i,(b(1).x,b(1).y)
End Sub

Sub Edgecollisions(b() As ball,xres As Long,yres As Long,Byref status As Long ) 'get status also
    Const k=50
    For n As Long=Lbound(b)+1 To Ubound(b)
        If(b(n).x<b(n).r) Then b(n).x=b(n).r: b(n).dx=-b(n).dx
        If(b(n).x>xres-b(n).r )Then b(n).x=xres-b(n).r: b(n).dx=-b(n).dx
        If(b(n).y<b(n).r)Then b(n).y=b(n).r:b(n).dy=-b(n).dy
        If(b(n).y>yres-b(n).r-k)Then  b(n).y=yres-b(n).r-k:b(n).dy=-b(n).dy
        If b(n).x<0 Or b(n).x>xres Then status=0
        If b(n).y<0 Or b(n).y>yres Then status=0
    Next n
End Sub

Function DetectBallCollisions( B1 As ball,B2 As ball) As Single 'avoid using sqr if they are well seperated
    Dim As Long xdiff = B2.x-B1.x
    Dim As Long ydiff = B2.y-B1.y
    If Abs(xdiff) > (B2.r+B1.r) Then Return 0
    If Abs(ydiff) > (B2.r+B1.r) Then Return 0
    Var L=Sqr(xdiff*xdiff+ydiff*ydiff)
    If L<=(B2.r+B1.r) Then Function=L Else Function=0
End Function

Sub BallCollisions(b() As ball)
    For n1 As Long=Lbound(b)+1 To Ubound(b)-1
        For n2 As Long=n1+1 To Ubound(b)
            If DetectBallCollisions(b(n1),b(n2)) Then
                Dim As Single  impulsex=(b(n1).x-b(n2).x)
                Dim As Single  impulsey=(b(n1).y-b(n2).y)
                Dim As Single ln=Sqr(impulsex*impulsex+impulsey*impulsey)
                impulsex/=ln'normalize the impulse
                impulsey/=ln
                'set one ball to nearest non overlap position ~digital to analogue workaround
                b(n1).x=b(n2).x+(b(n2).r+b(n1).r)*impulsex
                b(n1).y=b(n2).y+(b(n2).r+b(n1).r)*impulsey
               
                Dim As Single  impactx=b(n1).dx-b(n2).dx
                Dim As Single  impacty=b(n1).dy-b(n2).dy
                Dim As Single  dot=impactx*impulsex+impacty*impulsey
                Dim As Single  mn2=b(n1).m/(b(n1).m+b(n2).m),mn1=b(n2).m/(b(n1).m+b(n2).m)
               
                b(n1).dx-=dot*impulsex*2*mn1
                b(n1).dy-=dot*impulsey*2*mn1
                b(n2).dx+=dot*impulsex*2*mn2
                b(n2).dy+=dot*impulsey*2*mn2
            End If
        Next n2
    Next n1
End Sub
'steady framerate
Function Regulate(Byval MyFps As Long,Byref fps As Long) As Long
    Static As Double timervalue,lastsleeptime,t3,frames
    frames+=1
    If (Timer-t3)>=1 Then t3=Timer:fps=frames:frames=0
    Var sleeptime=lastsleeptime+((1/myfps)-Timer+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=Timer
    Return sleeptime
End Function

Sub display(b() As ball,xres As Long,yres As Long,f As Single=0)'all graphics
    #define map(a,b,x,c,d) ((d)-(c))*((x)-(a))/((b)-(a))+(c)
    Dim As Long status=1
    Edgecollisions(b(),xres,yres,status)
    BallCollisions(b())
    f=map((xres/2-300+20),(xres/2+300-20),b(0).x,0,2)
    Static As Long frate
    Dim As Single energy
    Screenlock
    Cls
    put(0,0),i,trans
    Line(0,768-50)-(1024,768-50),,b
    Var h=xres/2
    Line(h-300,768-48)-(h+300,yres-2),Rgb(100,100,100),bf
    MoveAndDraw(b(),energy,f)
    Draw String(10,yres-45), "framerate " &frate , Rgb(0, 200, 0)
    Draw String (10,yres-30),"System energy " &energy
    Draw String (h+310,yres-45),"System status " & Iif(status,"OK","Leaks")
    Screenunlock
    Sleep regulate(65,frate)
End Sub

Sub MoveByMouse(d() As ball,mx As Long,my As Long,button As Long,xres As Long,yres As Long)
    Dim As Long x=mx,y=my,dx,dy,b
    Dim As Long idx=d(0).x-mx,idy=d(0).y-my
    While button = 1
        If my<yres-50 Then Exit Sub
        display(d(),xres,yres)
        Getmouse mx,my,,button
        If mx>0 And my>0 Then
            If mx<>x Or my<>y Then
                dx = mx - x
                dy = my - y
                x = mx
                y = my
                d(0).x=x+dx+idx
                If d(0).x<xres/2-300+20 Then d(0).x=xres/2-300+20
                If d(0).x>xres/2+300-20 Then d(0).x=xres/2+300-20
            End If
        End If
    Wend
End Sub

Function Start() As Long
    Windowtitle "Brownian motion by mouse --- <esc> to end"
    #define range(f,l) Int(Rnd*(((l)+1)-(f)))+(f)
    #define incircle(cx,cy,radius,x,y) (cx-x)*(cx-x) +(cy-y)*(cy-y)<= radius*radius
    Dim  As ball b(0 To 300)
    Dim As Integer xres,yres
    Screen 20,32
    Color ,Rgb(0,0,50)
    Screeninfo xres,yres
    i=imagecreate(xres,yres)
    b(0).x=xres/2:b(0).y=743:b(0).col=Rgb(255,255,255):b(0).r=20 'moveable circle by mouse
    b(1).x=xres/2:b(1).y=yres/2:b(1).col=Rgb(255,255,255):b(1).r=30:b(1).m=b(1).r^2 'large circle
    For n As Long=Lbound(b)+2 To Ubound(b)
        With b(n)
            Do
                .x=range(20,(xres-20))
                .y=range(20,(yres-150))
            Loop Until incircle(b(1).x,b(1).y,2*b(1).r,.x,.y)=0
            .dx=(Rnd-Rnd)*2
            .dy=(Rnd-Rnd)*2
            .col=Rgb(Rnd*255,Rnd*255,Rnd*255)
            .r=10+Rnd*8
            .m=.r^2
        End With
    Next

    Dim As Long mx,my,btn
   While 1
        Getmouse mx,my,,btn
        display(b(),xres,yres)
       
        If incircle(b(0).x,b(0).y,b(0).r,mx,my) And btn=1 Then
            MoveByMouse(b(),mx,my,btn,xres,yres) 
        End If
       
      If Inkey=Chr(27) Then Exit While
    Wend
    Return 0
End Function

end Start
imagedestroy i
Sleep


 
badidea
Posts: 1997
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Brownian motion.

Postby badidea » Nov 18, 2019 22:58

dodicat wrote:Very quiet day on the forum today.

I guess everyone is working hard on some code.
dodicat wrote:This is slightly less exciting than watching paint dry.
...

I made something similar in 2007 to disprove the Brownian ratchet.
Link: viewtopic.php?f=3&t=16207&p=143310#p143306
deltarho[1859]
Posts: 2345
Joined: Jan 02, 2017 0:34
Location: UK

Re: Brownian motion.

Postby deltarho[1859] » Nov 19, 2019 9:34

@dodicat

What I often do with code using RND is to replace RND with PCG32II to see how they fair with a faster generator.

As posted your code compiles and runs without issue. However, when I added your code to the PCG32II folder and added #Include "PCG32II.bas" I got this.

Code: Select all

E:\FreeBASIC\PCG\BrownianMovement.bas(76) error 4: Duplicated definition, lastsleeptime in 'Static As Double timervalue,lastsleeptime,t3,frames'

E:\FreeBASIC\PCG\BrownianMovement.bas(81) error 119: Cannot modify a constant, before '=' in 'lastsleeptime=sleeptime'

E:\FreeBASIC\PCG\BrownianMovement.bas(81) warning 5(0): Implicit conversion

lastsleeptime is not used in PCG32II.bas.

Line 76 is 'Static As Double timervalue,lastsleeptime,t3,frames' in 'Function Regulate'.

To cut a long story short I replaced lastsleeptime with _lastsleeptime which you use in other code using 'Function Regulate' and I got a successful compile and run.

Two questions arise here: Why did the compilation fail with lastsleeptime and why was _lastsleeptime used in earlier code posted?

It seems to me that there is something about FreeBASIC that I am not aware of.
dodicat
Posts: 6365
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Brownian motion.

Postby dodicat » Nov 19, 2019 10:02

deltarho[]
Including windows.bi fetches a long enum with lastsleeptime at integer 15.
Thus the _lastsleeptime.

Compile this code with -pp switch and you will see it.

Code: Select all

#define WIN_INCLUDEALL
#include "windows.bi"
deltarho[1859]
Posts: 2345
Joined: Jan 02, 2017 0:34
Location: UK

Re: Brownian motion.

Postby deltarho[1859] » Nov 19, 2019 10:51

Thanks, dodicat.

In PCG32II.bas I have

Code: Select all

#ifdef __FB_WIN32__
  #Include Once "windows.bi"

It would be nice to be advised where the definition was being used elsewhere. With PowerBASIC if an include file (.inc) had an issue it gets loaded into the IDE.
MrSwiss
Posts: 3445
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Brownian motion.

Postby MrSwiss » Nov 19, 2019 17:02

FYI:
using dependencies (aka: OS related stuff, like WIN-API) is the typical PB way of thinking.
Switch to the FB way of thinking: only ever use OS related things, if it is 100% unavoidable.
As long as FB has got the functionality (e.g. Mersenne Twister) use that for seeding ...
(and forget WIN-Crypto-API) Then, you don't need "windows.bi" and there are no troubles ...
(This is targetting other PRNG's like PCG32 e.t.c. especially!)
dodicat
Posts: 6365
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Brownian motion.

Postby dodicat » Nov 19, 2019 17:08

fbide shows an include file if there is an error in it, (you can create a pseudo error)

Code: Select all

'fbide

dim as long lastsleeptime=32

#include "windows.bi"

dim as zstring * 32   Machine
dim as long   b = 32
 GetComputerName(Machine, @lastsleeptime)


messagebox(0,machine,"your box",0)

 
deltarho[1859]
Posts: 2345
Joined: Jan 02, 2017 0:34
Location: UK

Re: Brownian motion.

Postby deltarho[1859] » Nov 19, 2019 17:49

From PCG32II's Help file.
MyRandomize takes two Ulongint parameters: Seed and Sequence both of which are optional with a zero default.

For non-Windows platforms it uses a version of Get64Bit which in turn uses FreeBASIC's random number generator #5. For Windows platforms it uses a version of Get64Bit which generates a multiplicative prediction resistant 64-bit value based upon an Intel engineer's blog.

Mersenne Twister is one of the easiest generators to predict on the planet and why I use #5 for non-Windows platforms.

I use FileLocator Pro quite a lot but could not find 'lastsleeptime'. I later realized that I had forgotten to change the last filter used from *.bas to *.bi. 'lastsleeptime' is, in fact, in winnt.bi.

!! Content removed by moderator for relevance. !!

Added: Intel's RDSEED, which is multiplicative prediction resistant, was designed for seeding purposes but I only have RDRAND; and many folk don't even have that.
Last edited by Imortis on Nov 19, 2019 19:39, edited 1 time in total.
Reason: Uncivil behavior
MrSwiss
Posts: 3445
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Brownian motion.

Postby MrSwiss » Nov 19, 2019 18:13

!! Content edited by Moderator for relevance !!
Last edited by Imortis on Nov 19, 2019 19:39, edited 1 time in total.
Reason: Uncivil behavior
dodicat
Posts: 6365
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Brownian motion.

Postby dodicat » Nov 19, 2019 18:24

I have tested all the freebasic ides I have, there are plenty.
Only fbide brings up an include file to flag an error.
One thing about fbide, it is done and dusted, you use it warts and all.
No need for downloading never ending updates.
After all, the ide is only a tool to do what you want.
Enough work writing working code without being an eternal slave to some ide in development.
And a final outcome, some leviathan RAD environment goodness knows when.
No disrespect to the current ide developers.
deltarho[1859]
Posts: 2345
Joined: Jan 02, 2017 0:34
Location: UK

Re: Brownian motion.

Postby deltarho[1859] » Nov 19, 2019 18:30

!! Content edited by moderator for relevance !!
Last edited by Imortis on Nov 19, 2019 19:42, edited 1 time in total.
Reason: Uncivil behavior
deltarho[1859]
Posts: 2345
Joined: Jan 02, 2017 0:34
Location: UK

Re: Brownian motion.

Postby deltarho[1859] » Nov 19, 2019 18:50

dodicat wrote:One thing about fbide, it is done and dusted, you use it warts and all.
No need for downloading never ending updates.

Most manufacturers recommend a cambelt change every 40,000 to 60,000 miles. Our free timing belt check will help if you're unsure whether it's time for a replacement.

I mentioned this at one of my services and the mechanic said I need not worry about that because my car, built in 2002, did not have one. Image I bought the vehicle when it was three years old and still in short trousers. When it starts to cost money because of its age is when it will be scrapped.

!! Content edited by moderator for content !!
Last edited by Imortis on Nov 19, 2019 19:42, edited 2 times in total.
Reason: Uncivil behavior
Imortis
Moderator
Posts: 1715
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Brownian motion.

Postby Imortis » Nov 19, 2019 19:37

Come on, everyone. Must we do this? I have edited some posts here to remove some of the more directed snipes, but please stop.

There should be nothing wrong with differences of opinion or coding style or preference, but please stop antagonizing one another. This is getting a bit more childish than I would like to see. If you both can't settle down, other measures may need to be taken.
paul doe
Posts: 1175
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Brownian motion.

Postby paul doe » Nov 19, 2019 20:02

Imortis wrote:...
There should be nothing wrong with differences of opinion or coding style or preference, but please stop antagonizing one another. This is getting a bit more childish than I would like to see. If you both can't settle down, other measures may need to be taken.

You're not being quite fair here, Luther. If you're personally attacked by someone every f****** time you post something, wouldn't you react in an 'uncivilized' way too? And it seems to me that David even takes it with a little quota of humor. So, speaking of 'both' is, in this particular case, just plain wrong. We all see where the real problem lies; but also the mods/admins being unwilling to take the appropriate measures. Time for 'talking' and 'settling' is past (David already tried that, to no avail). I (and I take it that many other members also think alike) am quite sick of this situation. Jeff said that there's 'a valid point or two', but the point is moot: even a broken clock gives the exact time twice a day.
deltarho[1859]
Posts: 2345
Joined: Jan 02, 2017 0:34
Location: UK

Re: Brownian motion.

Postby deltarho[1859] » Nov 19, 2019 20:27

@Imortis

Re my last post: "Reason: Uncivil behavior."

Are you joking? If you paid attention you will have realized that dodicat and I get on so well we sometimes pull each other's legs and there is never any antagonism between us.

The situation with MrSwiss is a very different kettle of fish. If you paid attention you will have realized that I never start any antagonism, I respond to antagonism.

If I was a moderator I would have jumped on "is the typical PB way of thinking." but you did not and it is still there.
If you both can't settle down, other measures may need to be taken.

The only solution that I can think of is to not enter a thread that MrSwiss is posting in or stop posting in a thread if MrSwiss starts to post in a thread.
Paul wrote:We all see where the real problem lies; but also the mods/admins being unwilling to take the appropriate measures.

We have been here before have we not?

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 1 guest