|
Post by tenochtitlanuk on Mar 25, 2022 9:46:06 GMT -5
The code is very much a beginning, or work-in-progress. I am looking in this version at what happens if the birds are simply attracted to the centre of mass of their neighbours, and tire slowly. Hence earlier use of velocity terms is remmed out. Do they end in systematic or chaotic orbits? Plenty of other rules to consider. I've looked at some possibilities, and each uses the same kind of code. It is of course much slower when you have to know which are your nearest neighbours... and I've yet to digest what you and the others have achieved. I just like putting pretty graphics on the Forum! As with most coding, I've got far enough so far only to have got good ideas on how to rewrite it better!
However I've just been in Northumbria for a week, then in Cornwall for a week, and at present have ten days with my son from the US who we've not seen in the flesh for three years plus. Priorities .... J
|
|
bplus
Full Member
 
Posts: 123
|
Post by bplus on Mar 25, 2022 13:38:19 GMT -5
Hey John, the code seems to have the rule code remmed out. Is that deliberate? Do I have the right code? No remming here: ' ******************************************** ' ** ** ' ** tenochBoids4.bas 16/03/21 ** ' ** ** ' ** create a field of flocking boids ** ' ** ** ' ********************************************
nomainwin
WindowWidth =1120 WindowHeight = 630
' Each boid represented in a csv string of x, y, vx, vy ' x/y onscreen if in o...600. Velocity of 1 represents one pixel per cycle.
global xCG, yCG ' coordinates of centre of gravity of flock
N = 50 ' number of boids dim boid$( N)
open "Tenochtitlanuk Boids" for graphics_nsb as #wg
#wg "trapclose quit" #wg "down ; size 10 ; fill 80 80 255"
loadbmp "scr", "sky.bmp"
gosub [createBoidField]
[next] ' cycle the updates gosub [drawBoidField] gosub [updateBoidField] scan goto [next] ' __________________________________________________________
[createBoidField] for i =0 to N -1 x = 50 +1000 *rnd( 1) y = 50 + 500 *rnd( 1) vx = 2 + 8 *rnd( 1) -4 vy = 2 + 8 *rnd( 1) -4 boid$( i) =str$( x) +"," +str$( y) +"," +str$( vx) +"," +str$( vy) next i return
[drawBoidField] ' draw current flock. #wg "cls ; drawbmp scr 1 1" #wg "color red ; size 5 ; up ; goto 2 2 ; down ; box 1105 597 ; up" for i =0 to N -1 call drawBoid boid$( i) scan next i return
[updateBoidField] ' calculate new boid flock. gosub [findCofG] ' find xCG, yCG of centre of mass
for K =0 to N -1 x =val( word$( boid$( K), 1,",")) y =val( word$( boid$( K), 2,","))
R$ =rule1$( K)
vx =val( word$( boid$( K), 3, ",")) -( x -xCG) /10000'-1e-1 *val( word$( R$, 1, ",")) *sin( val( word$( R$, 2, ","))) ' *angle fn.) vy =val( word$( boid$( K), 4, ",")) -( y -yCG) / 6000'-1e-1 *val( word$( R$, 1, ",")) *cos( val( word$( R$, 2, ",")))
vx =0.9999 *vx vy =0.9999 *vy
x =x +vx y =y +vy
if x <=10 or x >=1090 then vx =0 -0.9 *vx ' implements ricochets off sides. if y <=15 or y >= 585 then vy =0 -0.9 *vy ' could instead wrap top/bottom and left/right- toroid world.
boid$( K) =str$( x) +"," +str$( y) +"," +str$( vx) +"," +str$( vy) scan next K return
[findCofG] ' place CofG position in global xCG, yCG. xCG =0: yCG =0 for f =0 to N -1 xCG =xCG +val( word$( boid$( f), 1, ",")) yCG =yCG +val( word$( boid$( f), 2, ",")) next f xCG =( xCG /N +500) /2 yCG =( yCG /N +300) /2 return
function rule1$( K) ' accelerate towards centre of mass of flock. dx =val( word$( boid$( K), 1, ",")) -xCG dy =val( word$( boid$( K), 2, ",")) -yCG R =( dx^2 +dy^2)^0.5
angle =Atan2( dy, dx) rule$ =str$( R) +"," +str$( angle) ' return a string with magnitude and angle of accn towards CofG end function
sub drawBoid i$ ' draw an individual boid #wg "color darkblue" ' draw boid #wg "size 10 ; down" x =val( word$( i$, 1, ",")) y =val( word$( i$, 2, ",")) #wg "set "; int( x); " "; int( y) vx =val( word$( i$, 3, ",")) vy =val( word$( i$, 4, ",")) magn =( vx^2 +vy^2)^0.5 dirn =Atan2( vy, vx) nx =x +vx ny =y +vy #wg "color black" ' draw tail, length proportional to velocity and along track #wg "size 1" #wg "goto "; x -4 *vx; " "; y -4 *vy end sub
Function Atan2( y, x) If x = 0 Then If y < 0 Then Atan2 = -1.5707963267948967 Else Atan2 = 1.5707963267948967 End If Else chk = atn(y/x) If x < 0 Then If y < 0 Then chk = chk - 3.1415926535897932 Else chk = chk + 3.1415926535897932 End If End If Atan2 = chk End If 'thanks Andy Amaya ( one of several versions I use) End Function
sub quit h$ close #h$ end end sub
|
|
|
Post by Rod on Mar 25, 2022 14:42:32 GMT -5
The line that applies the R$ rule is remmed out half way through. But like many of my versions it explores what is possible. I was hoping to use the turn code. Using the entire flock CoG is a possible time saver. I was planning to calculate one cycle and use the next.
|
|
bplus
Full Member
 
Posts: 123
|
Post by bplus on Mar 25, 2022 15:07:58 GMT -5
vx =val( word$( boid$( K), 3, ",")) -( x -xCG) /10000'-1e-1 *val( word$( R$, 1, ",")) *sin( val( word$( R$, 2, ","))) ' *angle fn.) vy =val( word$( boid$( K), 4, ",")) -( y -yCG) / 6000'-1e-1 *val( word$( R$, 1, ",")) *cos( val( word$( R$, 2, ",")))
OH I see it now!
I was wondering how this:
[findCofG] ' place CofG position in global xCG, yCG. xCG =0: yCG =0 for f =0 to N -1 xCG =xCG +val( word$( boid$( f), 1, ",")) yCG =yCG +val( word$( boid$( f), 2, ",")) next f xCG =( xCG /N +500) /2 yCG =( yCG /N +300) /2 return
Could possibly work but running it, the ave bird locations do seem to change quadrants over time, magic I guess.
|
|