![]() |
Forum Index : Microcontroller and PC projects : CMM2: V5.05.06b16 - Brownian motion demo using sprites
Author | Message | ||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10310 |
You will need to download V5.05.06b16 for this demo as it uses a couple of new SPRITE functions: http://geoffg.net/Downloads/Maximite/CMM2_Beta.zip SPRITE(T,spriteno) ' returns a bitmap showing all the sprites currently in collision with the requested sprite. Bits 0-63 in the returned integer represent a current collision with sprites 1 to 64 respectively SPRITE(E,spriteno) ' returns a bitmap showing which if any edges of the screen the sprite is in contact with: If sprite(E,spriteno) AND 1 Then 'collision with left of screen Else If sprite(E,spriteno) AND 2 Then 'collision with top of screen Else If sprite(E,spriteno) AND 4 Then 'collision with right of screen Else If sprite(E,spriteno) AND 8 Then 'collision with bottom of screen In addition b16 fixes an issue with SPRITE HIDE ALL status not being cleared correctly This demo hammers the SPRITE engine with 64 sprites moving all over the screen and never being allowed to overlap. Video here ![]() option explicit option default none option console serial mode 7 page write 1 'brownian motion demo using sprites dim integer x(64),y(64),c(64) dim float direction(64) dim integer i,j,k, collision=0 dim string q$ for i=1 to 64 direction(i)=rnd*360 'establish the starting direction for each atom c(i)=rgb(rnd*255,rnd*255,rnd*255) 'give each atom a colour circle 10,10,4,1,,rgb(white),c(i) 'draw the atom sprite read i,6,6,9,9 'read it in as a sprite next i cls box 0,0,mm.hres,mm.vres k=1 for i=mm.hres\9 to mm.hres\9*8 step mm.hres\9 for j=mm.vres\9 to mm.vres\9*8 step mm.vres\9 sprite show k,i,j,1 x(k)=i y(k)=j vector k, direction(k), 0, x(k), y(k) 'load up the vector move k=k+1 next j next i ' do for i=1 to 64 vector i, direction(i), 1, x(i), y(i) sprite show safe i,x(i),y(i),1 if sprite(S,i)<>-1 then break_collision i endif next i page copy 1 to 0 loop ' Sub vector(obj As integer, angle As float, distance As float, x_new As integer, y_new As integer) Static float y_move(64), x_move(64) Static float x_last(69), y_last(64) Static float last_angle(64) If distance=0 Then x_last(obj)=x_new y_last(obj)=y_new EndIf If angle<>last_angle(obj) Then y_move(obj)=-Cos(Rad(angle)) x_move(obj)=Sin(Rad(angle)) last_angle(obj)=angle EndIf x_last(obj) = x_last(obj) + distance * x_move(obj) y_last(obj) = y_last(obj) + distance * y_move(obj) x_new=Cint(x_last(obj)) y_new=Cint(y_last(obj)) Return ' keep doing stuff until we break the collisions sub break_collision(atom as integer) Local integer j=1 local float current_angle=direction(atom) 'start by a simple bounce to break the collision If sprite(e,atom)=1 Then 'collision with left of screen current_angle=360-current_angle Else If sprite(e,atom)=2 Then 'collision with top of screen current_angle=((540-current_angle) Mod 360) Else If sprite(e,atom)=4 Then 'collision with right of screen current_angle=360-current_angle Else If sprite(e,atom)=8 Then 'collision with bottom of screen current_angle=((540-current_angle) Mod 360) Else 'collision with another sprite or with a corner current_angle = current_angle+180 endif direction(atom)=current_angle vector atom,direction(atom),j,x(atom),y(atom) 'break the collision sprite show atom,x(atom),y(atom),1 'if the simple bounce didn't work try a random bounce do while (sprite(t,atom) or sprite(e,atom)) and j<10 do direction(atom)= rnd*360 vector atom,direction(atom),j,x(atom),y(atom) 'break the collision j=j+1 loop until x(atom)>=0 and x(atom)<=MM.HRES-sprite(w,atom) and y(atom)>=0 and y(atom)<=MM.VRES-sprite(h,atom) sprite show atom,x(atom),y(atom),1 loop ' if that didn't work then place the atom randomly do while (sprite(t,atom) or sprite(e,atom)) direction(atom)= rnd*360 x(atom)=rnd*mm.hres-sprite(w,atom) y(atom)=rnd*mm.vres-sprite(h,atom) vector atom,direction(atom),0,x(atom),y(atom) 'break the collision sprite show atom,x(atom),y(atom),1 loop End Sub |
||||
PeteCotton![]() Guru ![]() Joined: 13/08/2020 Location: CanadaPosts: 543 |
Very cool! Thanks! |
||||
Nimue![]() Guru ![]() Joined: 06/08/2020 Location: United KingdomPosts: 420 |
Nice I remember a simulation I used years ago that did exactly this - great work in bringing to the CMM2. IIRC the sim I used set the concept of particle kinetic energy, linked to the "temperature" in the box. You could vary the box size, number of particles and the temperature. IIRC it also then calculated the "pressure" inside the box -- students could then essentially simulate PV=nRT - and get data for the ideal gas equation. What you have here is a huge step towards that - thanks for sharing. I'm loving how versatile the CMM2 is - "the little box that can" << I'll gift that to The Shed -- and expect to see it on a Tee-shirt sometime soon. Nim Entropy is not what it used to be |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10310 |
Good ![]() Any chance you can help by defining the correct equation for two atoms colliding and I'll include it as it is completely wrong at the moment. I see a collision and know the velocity and direction of both atoms. I need to calculate the new velocity and direction for each of them. At the moment the velocity is always the same and they are assumed to be the same mass so that simplifies things. |
||||
Nimue![]() Guru ![]() Joined: 06/08/2020 Location: United KingdomPosts: 420 |
The ideal gas equation assumes: (1) All point masses - ie radius is zero --- but we cant sim that. The assumption we use is that total area of all the particles is small compared to the size of the box (1% ish) -- but that is often overlooked when simming so that we can detect collisions (2) That all particles have the same mass (3) That all collisions are elastic - ie the total momentum before = momentum after (ie no energy is lost / the individual particles do not get warmer as they collide) The kinetic energy (1/2 mv^2) is 3/2 x nRT -- where R is a constant (approx 8) and n = number of moles (assume 1 for the sake of simulation) -- so KE = 12T (where T is in Kelvin). This gives mv^2 = 24T v = SQRT (24T/m) v is conserved during a collisions. Pressure x Volume (in our case sub for area of box) = nRT (n=1, R=8) = 8T Pressure on box = 8T/Volume (use area as 2D) (assuming n=1)_ As you describe your assumptions should work out - don't think you need to alter them for this to be calculated... Entropy is not what it used to be |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10310 |
Its the directions after the collision I'm struggling with atom one of mass M is moving at speed V in direction theta1 atom two of mass M is moving at speed V in direction theta2 the atoms are assumed to be round and collide, I know the vector from the centre of atom1 to the centre of atom2 What is theta3 the new direction for atom 1 and theta4 the new direction for atom 2? Edited 2020-10-04 04:27 by matherp |
||||
Nimue![]() Guru ![]() Joined: 06/08/2020 Location: United KingdomPosts: 420 |
Hi Does this help -- better than me trying to draw it https://www.youtube.com/watch?v=H4cIOgBV3Qw&feature=emb_logo Nim Entropy is not what it used to be |
||||
romba6![]() Newbie ![]() Joined: 04/07/2020 Location: United KingdomPosts: 37 |
When I bought my CMM2 I thought, as an ex-hardware engineer, I would enjoy the build, which I did & learn to improve my very limited BASIC programming – which I am slowly doing! However, I’ve come across words like quarternions – which totally by-passed me in Maths at school, & Brownian motion, yes, I missed out on that too as well as umpteen other maths, science and sound subjects. I then spend lots of time, which I have, on Wikipedia etc. reading, learning and trying to understand all these things. I so thoroughly enjoy reading about all these topics and so grateful to all the contributors who broaden my horizons with, not only their programming skills, but in the way they apply them in so many colourful & various ways. Thank you!! |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4311 |
Another masterclass Peter. May I have permission to include it on the Welcome Tape please? Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
What do the collisions look like if you just swap velocities? Ie: if 1 and 2 collide, 1 takes on the velocity of 2 and vice versa, without swapping positions, where velocity is speed and direction. Visit Vegipete's *Mite Library for cool programs. |
||||
panky![]() Guru ![]() Joined: 02/10/2012 Location: AustraliaPosts: 1114 |
Excellent Peter, May I also add it to the Graphics Programming Manual please? Doug. ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
After nearly 3 hours running, it finally gave up with Jim VK7JH MMedit |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10310 |
Oops missed a bracket x(atom)=rnd*(mm.hres-sprite(w,atom)) y(atom)=rnd*(mm.vres-sprite(h,atom)) Also change line 33 sprite show i,x(i),y(i),1 Any Basic code I post can be used for any purpose - appreciate the courtesy but no need to ask I'll have a play later today and see if I can get the physics better Edited 2020-10-04 19:22 by matherp |
||||
paceman Guru ![]() Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
I have a nagging feeling that I'm missing something obvious but is anyone else having a problem with an "UNKNOWN COMMAND" error popping up when a label, that does have it's following colon, is on a line by itself - i.e. no code on the same line, after the colon? It's happened to me with a number of programs I've downloaded and copied to the SD card using my Win7 notepad. I'm running the b15 firmware currently. Greg |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10310 |
Install the latest b17 |
||||
paceman Guru ![]() Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
That's fixed it Peter, thank you. You'd have to be the fastest developer in the West - err... North. Thanks again, Greg |
||||
vegipete![]() Guru ![]() Joined: 29/01/2013 Location: CanadaPosts: 1132 |
Not sure where to put this, but half is about sprites so... 1) Could another SPRITE() function be added that returns the distance between (the centers of) two sprites? For example, dist = SPRITE(D,spriteno1,spriteno2). This would complement SPRITE(V,...) nicely. (Which ought to be SPRITE(A,...) since it returns the angle. ;-) 2) Could the y-coordinate of PRINT @(x,y) be made optional. If not given, the existing y value is used. Then, something like for i = 1 to 10 would print a column of numbers down the horizontal center. This would operate similar to the good old TAB function: "PRINT TAB(20); i"print @(MM.HRES/2,) i next i Visit Vegipete's *Mite Library for cool programs. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10310 |
For example, dist = SPRITE(D,spriteno1,spriteno2). This would complement SPRITE(V,...) nicely. (Which ought to be SPRITE(A,...) since it returns the angle. ;-) 2) Could the y-coordinate of PRINT @(x,y) be made optional. If not given, the existing y value is used. Then, something like Both good ideas, will include in next beta |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |