Author Topic: Build a Solar System  (Read 807 times)

0 Members and 1 Guest are viewing this topic.

Offline Hydrophilic

  • 128D user
  • *******
  • Posts: 1430
  • Reputation: 233
  • Gender: Male
    • View Profile
    • H2Obsesson
Build a Solar System
« on: September 13, 2011, 10:23 AM »
I wanted to test out my mouse/joystick driver before putting into MP128 (so I could test in a simpler environment), so I made this BASIC program which I thought was fairly simple (more about that later).
 
The program just models the gravitational force of n-bodies in 2 dimensions.  To use it, attach the disk to unit 8 and power-up to auto boot, or you can enter RUN"PLANETS" after power-up.  It doesn't need to be in disk unit 8.  It should even work from cassette but I haven't tried it.
 
Once the program is loaded, the screen is cleared and you have 3 menu options.  Plug a mouse into port 1 or a joystick into port 2 (or both, that's a fun game with a friend/enemy!)  You can also use the keyboard for most operations (all except drag-n-drop).
 
Building a Solar System
To start building, click Add or press A.  You get the New Body menu where you set the mass, velocity (speed), and color of the new body.  I always start with a star = mass of 1000 and speed 0.  Whenever you're done setting the options for the body (star / planet / comet ) click O.K. or press Return.
 
Your new body will be attached to the cursor and you can move anywhere on the screen you like.  When you find a nice location, click on the spot set the initial position.  If you gave your body a non-zero speed then it should start moving right away.  Even if you gave your new body a zero speed, it should start moving soon if there are other bodies present (gravitational attraction).
 
Of course adding only 1 body (a star for example) is rather pointless.  So you will want to Add at least one more body.  If you added a star like described above, the second thing to try might be to add a planet.  A large jupiter-size planet should have a mass of about 1.0.  A small earth-size planet should have a mass of 0.01 or less.
 
Whatever mass you give to your planet/comet, be sure to give it some velocity.  If you give it zero velocity, it will simply fall into the star.  A good starting condition is to place the planet on the same horizontal line as the star, and give the planet an x-velocity of 0 and y velocity of non-zero (1 to 10 depending on distance).  Or you can place it on the same vertical line as the star and give your planet a non-zero x-velocity and zero y-velocity.  I hope that makes sense!  Basically you want the planet to move perpendicular (at right angle) to the star.
 
It's easy to get 2 bodies to orbit.  When you try adding a third, you may find it rather challenging to find an oribt that is stable for all bodies.  This is the so-called n-body problem.  If you don't do a good job of guessing a starting positition/speed/mass for the 3+ body, then it or one of the other bodies will likely get ejected from your solor system.
 
Editing and Deleting Bodies
If you see one of your planets flying off into deep space, or if you're just not happy with it, you can change or delete it.  Just click on the body you're interested in, and you'll get the Edit Body menu.  This works just like the Add body menu.  You can change the velocity, mass, or color.  You can delete the body from your solor system by clicking Delete (or press ESC).  Otherwise, click O.K. when you're happy with the new settings, and you get the option to reposition the body.  If you click Yes (or type Y) then you can move it anywhere, just like when you add a new body.  If you click No (or type N) then body returns to it's previous location but with the new properties you just defined.
 
Demo
Hopefully you'll have some fun trying to build a nice solor system.  It can be quite a challenge with multiple planets which have a large variety of mass.  In fact it can be quite frustrating.  To demonstrate it can be done, you can choose Demo from the main menu.  Then you can select the number of bodies to model, 1 to 7.  Selecting only 1 is a bit silly as you'll just have a lonely star sitting in the middle of the screen.  Although the n-body problem is a challenge, I got those demo settings after playing around with it for a day.  Then I went to sleep without turning off my computer by accident.  The next morning I was pleasantly suprised to see all my planets were still in orbit   The question is, would be it stable for 4.5 billion years?  I think not.
 
Quit
Bored already?  Click Quit (or press Q) from the main menu to end the program and turn off all sprites except the pointer, so you can test it outside the program (or with other programs).  If you want to restore the defualt IRQ routine (disable mouse/joystick control of pointer) then type SYS DEC("B83").  Or simple press STOP+RESTORE.
 
Technical
The program was meant to test the joystick/mouse driver, so it is not very sophisticated.  The most noticable thing is scaling: because VIC pixels are not square, a planet in a circular orbit will apear to be in an eliptical orbit.  Another thing is no provision for collisions: bodies just pass through one another.  Finally there is the issue of units.  The program doesn't use standard units of mass, distance, and velocity.
 
All of the above could be corrected fairly easily, by employing some constants in the equations, but that would just slow the simulation down.  It seems to run okay with 2 or 3 bodies, but beyond that you will notice it becomes slugish.  I compiled the BASIC program to make it faster, but it didn't help much.  Usually when you compile a BASIC program, it will be 10x faster (or more).  However due to lots of floating-point calculations, a poor compiler, or my bad programing, it runs only about 2x faster when compiled. 
 
I tried compiling it with Data Becker's 128 Compiler (v1.03) but it gave me lots of trouble.  That compiler kept giving me errors about BEGIN/BEND.  And it doesn't perform IF X correctly.  That's just terrible in my opinion!  I tried re-writing my program with GOTOs and IF X>0, and eventually got past those problems, but then there was a problem with STR$().  It seems if their are 8 digits after the decimal point the run-time version will crash randomly (depending on the digit before the decimal point).  At this point I gave up on that compiler.
 
Next I tried Blitz! 128.  This compiler doesn't have as many options (in particular, no native 6502 ML), but at least it works!  I think maybe the speed could be improved if the variables were accessed in 1-d arrays instead of a 2-d array.  However I've spent too much time on this already, so didn't investigate the possibility.
 
Anyway, the compiled program "PLANETS" is what is normally run.  The disk image also includes "PLANETS.BAS" which is the uncompiled version.  Should you want to play with it.  Also on the disk, "PLANETS.SPR" are the 7 sprites (besides the pointer) used in the program.  They should load to $E40~$FFF.  Also on the disk is "MJ-G-DRV.BIN" which is the mouse/joystick driver with Group option (for drag-n-drop).  This is the ML driver used in the program, and loads to the area $B80~$E3F (it includes the sprite pointer).  Not used in the program, but also on the disk is "MJ-DRV.BIN" which is the smallest version I could make.  It loads into $E00~$FFF and includes a sprite for the pointer but does no sprite grouping (no drag-n-drop); more importantly the memory used for BASIC sprites 2~7 are instead used by IRQ code.
 
Theory
I was suprised the compiled version was so slow considering the BASIC algorithim is simple (to me anyway).  Here it is,
 
FOR I=1 TO N-1
AX=AX(I):AY=AY(I):M1=M(I)
FOR J=I+1 TO N
DX=PX(I)-PX(J):DY=PY(I)-PY(J):M2=M(J)
L2=DX*DX+DY*DY
F=M1*M2/L2
L=SQR(L2)
FX=F*DX/L:FY=F*DY/L
AX=AX+FX/M1:AY=AY+FY/M1
AX(J)=AX(J)-FX/M2:AY(J)=AY(J)-FY/M2
NEXT J
AX(I)=AX:AY(I)=AY
NEXT I
 
Well that's the theory.  In the program the outer loop is DO/LOOP and not FOR/NEXT because some elements (planets) might be missing (if you deleted them) and a check of mouse/keyboard/joystick can break the loop.  I also optimized away the division of L by making it a part of the F calculation.  Anyway, this calculates the forces (and gravitational acceleration) between all possible pairs of bodies.  The number of times this loops is related to the square of the number of bodies.  Specifically
 
number of inner iterations = (N-1)*N/2.
 
So with 3 bodies, there are only 3 iterations.  But with 4 bodies there are 6 iterations.  With all 7 bodies, there are 21 iterations of all that code.
 
Finally there is more code to take the accelerations calculated above and apply them to the velocity/position of each sprite (and also reset the acceleration).  So as you can see, BASIC has a lot of work to do.  So maybe now you can see why it runs slugish with 4 or more bodies.
 
The End
Well it works for me in VICE with joystick or mouse or on my C128 with a joystick (actually a sega game pad).  Unfortunately I don't have mouse any more for my C128, so if anybody with a real C128 and mouse would care to report how it works, or fails, I'd love to hear about it!
 
Edit
Corrected some typos... it seems I can spell gravitational acceleration but not solar... thanks Naquaada
« Last Edit: September 15, 2011, 08:07 AM by Hydrophilic »
I'm kupo for kupo nuts!

Offline airship

  • 128D user
  • *******
  • Posts: 1605
  • Country: us
  • Reputation: 114
  • Gender: Male
  • Former Editor, INFO Magazine
    • View Profile
    • Atomic Airship
Re: Build a Solor System
« Reply #1 on: September 14, 2011, 08:19 AM »
Very nice.

But you know, you could have made a MUCH simpler program just to test the mouse.

NOW GET BACK TO WORK!!! :D
Serving up content-free posts on the Interwebs since 1983.
History of INFO Magazine

Offline Hydrophilic

  • 128D user
  • *******
  • Posts: 1430
  • Reputation: 233
  • Gender: Male
    • View Profile
    • H2Obsesson
Re: Build a Solar System
« Reply #2 on: September 15, 2011, 08:26 AM »
I wanted to make an interesting program to motivate people to try it and hopefully report how the mouse works on a real C128.  I also wanted to see how much a compiler could help a BASIC program.
 
I think the program is pretty simple.  The mouse menu stuff makes it messy / hard to read.
 
I have been working!  I got the VDC pointer working now.  It works well by itself or with the mouse/joystick driver in this example.  I think I'll write a small ML library to handle the menus, based on the ugly BASIC in this example.
I'm kupo for kupo nuts!

Offline RCtech

  • VIC 20 user
  • ****
  • Posts: 190
  • Country: de
  • Reputation: 2
    • View Profile
Re: Build a Solar System
« Reply #3 on: September 15, 2011, 07:42 PM »
Are you using the VDC mouse pointer in text or in graphics mode? Maybe it would be possible write a small sprite handler identical to the VIC's for one or two sprites (mouse and text cursor), like in GEOS. If there's a change from 40/80 mode only the sprite number and the max x resolution has to be changed.

I presume your routine should be made for apps (mouse cursor/menus), maybe you could insert a small window creation routine? I had one from the 64'er magazine which I used in my vocabluary program these times. It was nothing specific with background restauration, only a help to draw rectangled windows with optional title, frame and shadow.

Offline Hydrophilic

  • 128D user
  • *******
  • Posts: 1430
  • Reputation: 233
  • Gender: Male
    • View Profile
    • H2Obsesson
Re: Build a Solar System
« Reply #4 on: September 16, 2011, 02:27 PM »
The VDC pointer is for text mode.  The code would need significant rework for bitmap mode.  The pointer follows the location of VIC sprite 1.  So you can use it without the mouse/joystick driver.  For example, you can turn the VDC pointer on and then issue MOVSPR 1,135#4 and then just sit back and watch the arrow move accross the screen automatically.  Of course you could upload a different character definition than an arrow/pointer... like a car or airplane or whatever.  So it is like a text-mode sprite for the VDC.  That's kind of silly, but it works well for text-based menus when using the mouse/joystick driver.
 
I'm sure I tried one or more of those type-in programs for menus / windows back in the day.  But because of memory issues, I'm not doing anything that special.  The ML I've written so far (less than 200 bytes) is mostly to find which item on the screen has been clicked because it would take BASIC forever to search through a large list.  BASIC seems fast enough for drawing menus.
I'm kupo for kupo nuts!