Orbiter-Forum Orbital mechanics simulator in Flash
 Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

 Math & Physics Mathematical and physical problems of space flight and astronomy.

 01-12-2009, 02:41 PM #1 cr1 Promoting vegetables in space Orbital mechanics simulator in Flash I'm thinking to make an orbital mechanics / gravity simulator in (Adobe) Flash, similar to the one found here: http://www.dan-ball.jp/en/ (which is in Java). The features will be the same as the Java version of the simulator to start with. Does anyone have any tips and/or any ideas about the equations that would have to be involved in this? Thanks
 01-12-2009, 03:49 PM #2 Scarecrow Orbinaut Quote: Originally Posted by cr1  Does anyone have any tips and/or any ideas about the equations that would have to be involved in this? Well for any gravity/orbital mechanics simulator, there's not much you really need to know. Here's some of it: F=GMm/(r^2) Force of gravity = Gravitational constant(google can help) * mass of object 1 * mass of object 2 / square of distance between them Use this on every pair of objects, and add the resulting force to both objects. a=F/m acceleration = Force/mass Use this to find how much each object accelerates as a result of the total force on it. V=v+at Final velocity = initial velocity + acceleration*timestep length Use this to find out what the new velocity of each object is at each timestep. The length of one timestep is your program's approximation of "instantaneous". This should be a small amount of time, for obvious reasons. P=p+vt Final position = initial position + velocity * timestep Use this to find out how the velocity changes the position of the objects involved. Repeat for each object, for each timestep. There are more sophisticated ways of doing all of the above, but this is a good first order approximation, and if your timestep is small enough, you should get pretty good results. And remember, that's Newtonian physics, using only the force of gravity, and force, acceleration, velocity, and position are all vectors.
 01-12-2009, 03:55 PM #3 Scrooge McDuck Addon Developer Quote: Originally Posted by cr1  Does anyone have any tips and/or any ideas about the equations that would have to be involved in this? I often use: http://www.braeunig.us/space/orbmech.htm This is a very nice site, including practical/useful/realistic example problems! Used it for my own orbital mechanics simulator. Also, I remember comming across some site with tutorials on gravity simulators for flash games, will try to look it up! At a first look, googling for flash gravity simulation reveals some interesting tutorials to start with. regards, mcduck
 01-12-2009, 07:41 PM #4 Linguofreak Orbinaut Quote: Originally Posted by Scarecrow  P=p+vt P=p+vt+(1/2)at^2 Without the (1/2)at^2 term the simulator will act as if the velocity were being applied instantaneously once per timestep, rather than smoothly over the whole timestep.
 01-12-2009, 07:48 PM #5 Scarecrow Orbinaut Quote: Originally Posted by Linguofreak  P=p+vt+(1/2)at^2 Without the (1/2)at^2 term the simulator will act as if the velocity were being applied instantaneously once per timestep, rather than smoothly over the whole timestep. An example of the more sophisticated methods of doing things. While this does give more precision for a given timestep length, in the limit as the length of the timestep approaches 0, they yield the same results.
 01-13-2009, 12:13 PM #7 tblaxland Webmaster Quote: Originally Posted by Scarecrow  An example of the more sophisticated methods of doing things. While this does give more precision for a given timestep length, in the limit as the length of the timestep approaches 0, they yield the same results. Ah, I can only wish my timesteps would approach zero...
 01-14-2009, 07:24 PM #8 cjp Donator Quote: Originally Posted by Quick_Nick  Let me know if 'anything goes wrong.' Basically: Find the atan2 of the delta-x and delta-y between two planets. Then take the sine of that angle and multiply it by the other planet's 'gravity', and add all that to your x-velocity. Then take the cosine of the angle and multiply it by the other planet's 'gravity', and add that to your y-velocity. (DON'T FORGET THAT FLASH USES RADIANS FOR ATAN2, SIN, AND COS!) The 'gravity' of the other planet should be some number divided by the distance between the two planets sqared. (ex: 100/(Math.pow(distance, 2)) Don't know if anything goes wrong, except I don't see the timestep appearing in your equations. And it seems unnecessarily complicated. This is how I would do it, for each body B separately: First calculate the acceleration caused by a body A onto body B: Code: ```dx = xa - xb dy = ya - yb r = sqrt(dx^2 + dy^2) ax = dx * G * Ma / r^3 ay = dy * G * Ma / r^3``` Note that it says r^3 instead of r^2. This is because I also multiply with dx and dy, and I need an extra r to compensate for the size of these. The total effect of dx, dy and the extra r only changes the direction of the acceleration. Also, I calculated the acceleration directly, instead of calculating the force first. This is because the acceleration contains Mb in the denominator (a = F/Mb), and the gravity force contains it in the numerator, so we can cancel them out. Then, if you have more than two bodies, add all accelerations of different bodies A together: Code: ```ax = sum(ax_1 + ax_2 + ...) ay = sum(ay_1 + ay_2 + ...)``` Here, you should sum over all bodies, escept for B itself. Don't try to calculate the gravity of a body onto itself (you'll get a division by zero). Finally, do the "numerical integration": Code: ```vx = vx + ax * dt vy = vy + ay * dt px = px + vx * dt py = py + vy * dt``` This is the most simple integration method. There are much more accurate methods, but this one is the easiest to understand for beginners. In each timestep, you should do this for each body. So, in pseudo code: Code: ```array ax_total[], ay_total[] foreach body B: ax_total[B] = 0 ay_total[B] = 0 foreach body A: if A == B: skip this A Calculate ax and ay for A and B Add ax and ay to ax_total[B] and ay_total[B] foreach body B: Do numerical integration for B``` Last edited by cjp; 01-15-2009 at 12:13 PM. Reason: Fixed error (switched Ma and Mb)
 01-15-2009, 10:34 AM #9 Calsir Orbinaut Hi, a couple of pointers: First, in the link cr1 provided there is a central fixed gravity attractor that makes all the particles orbit around it rather than get off the screen. You can even add other attractors or repellers. Moreover, I think that the scattering of the bodies initial velocities and positions is quite important. Secondly, about the unit of measures and the magnitude of the constants, you can easily put the masses to be equal to 1 and tweak the gravitational constant to give meaningful and aesthetic orbits . For instance, from cjb's post we can write: Code: ```ax = -dx * G * Mb / r^3 ay = -dy * G * Mb / r^3``` the constants G and Mb, if the masses of your bodies are all equal, can be simply included in a single constant "k". The minus sign is to make the force attractive rather than repulsive. Lastly, but it's getting a little advanced, you can play with the exponent of the force equation. if F = -G m M / r^2, you can state generally that a = -k r^n, where k is any constant you like, and play with the exponent. For instance, n = -2 is like gravity. With n = 1 the bodies will behave as if they were linked by springs.
 01-15-2009, 12:21 PM #10 Quick_Nick Passed the Turing Test Quote: Originally Posted by cjp  In each timestep, you should do this for each body. So, in pseudo code: Code: ```array ax_total[], ay_total[] foreach body B: ax_total[b] = 0 ay_total[b] = 0 foreach body A: if A == B: skip this A Calculate ax and ay for A and B Add ax and ay to ax_total[b] and ay_total[b] foreach body B: Do numerical integration for B``` Cool. Here's a section of my Java code (I wrote the program again): Code: ``` for(int i = 0; i < objects; i++) { for(int j = 0; j < objects; j++) { if(i != j) { angle = Math.atan2(xpos[i] - xpos[j], ypos[i] - ypos[j]); distance = Math.hypot(xpos[i] - xpos[j], ypos[i] - ypos[j]); xvel[i] += Math.sin(angle) * (100/Math.pow(distance, 2)); yvel[i] += Math.cos(angle) * (100/Math.pow(distance, 2)); } } xpos[i] -= xvel[i]; ypos[i] -= yvel[i]; }``` I don't think this could be much more complicated than your way. 'objects' is the number of bodies to be displayed. (placed at random positions with slight random velocity) The '100' in (100/Math.pow(distance, 2)) can be changed to affect the acceleration of gravity. (every planet in this program is equal in mass) I have it set to 100 because it looks good at this timestep. (100FPS) Basically saying 100/d^2 is just leaving out the step of multiplying the acceleration of gravity and one divided by the distance sqared.
 01-15-2009, 12:40 PM #11 cjp Donator Quote: Originally Posted by Calsir   Code: ```ax = -dx * G * Mb / r^3 ay = -dy * G * Mb / r^3``` We both made a mistake here. I swapped Ma and Mb (already fixed that in my post) You incorrectly placed minus signs in front of dx and dy To give you an example for the minus signs: suppose A is right of B (xa > xb, ya == yb). Then, in my convention, dx > 0 and dy = 0. Gravity is an attracting force, so B will accelerate to the right. So, ax has to become positive. G, Ma and r are all positive, so G*Ma/r^3 is positive. dx is also positive, so everything is OK without the minus sign. Quote: Originally Posted by Calsir  Lastly, but it's getting a little advanced, you can play with the exponent of the force equation. if F = -G m M / r^2, you can state generally that a = -k r^n, where k is any constant you like, and play with the exponent. For instance, n = -2 is like gravity. With n = 1 the bodies will behave as if they were linked by springs. You are a mathematician, aren't you? -----Post Added----- Quote: Originally Posted by Quick_Nick  I don't think this could be much more complicated than your way. Not much more complicated, but it uses trigonometry, while I use vector calculus. I prefer (cartesian) vector calculus, because it doesn't have as many nasty singularities (e.g. the direction of a line of length 0) and things like multiple representations of the same position (e.g. 0 degree == 360 degree). Further, if you want to do number crunching, it's usually faster. Finally, for me it's more straightforward to understand, but maybe that's different for other people. I also use two loops for a slightly more accurate numerical integration. When I leave that away, and also use some other of your simplifications, for comparison with your code, my code would look like this: Code: ``` for(int i = 0; i < objects; i++) { for(int j = 0; j < objects; j++) { if(i == j) continue; dx = xpos[j] - xpos[i]; dy = ypos[j] - ypos[i]; distance = sqrt(dx*dx + dy*dy); xvel[i] += dx * 100 / Math.pow(distance, 3); yvel[i] += dy * 100 / Math.pow(distance, 3); } } xpos[i] += xvel[i]; ypos[i] += yvel[i]; }``` (Why do you have -= instead of += on the velocity-to-position integration?)
 01-15-2009, 01:01 PM #12 Quick_Nick Passed the Turing Test Quote: Originally Posted by cjp  (Why do you have -= instead of += on the velocity-to-position integration?) Well I have to put a negative somewhere (just about anywhere ) so that y is increasing if the other object is lower on the screen. (y increases as you go down on a computer screen) I honestly have no idea why I had to put a negative on the x. Doing the math, I shouldn't have to. And I don't think I did have to the first time I made the program. But this time around, it seems necessary. I just tried your version of the code and it works just fine. I'm not sure how you got an exponent of 3 to get rid of the need for the angle.
 01-16-2009, 04:29 PM #13 Calsir Orbinaut Quote: Originally Posted by cjp  We both made a mistake here. Unlikely, I hardly _ever_ make mistakes . Sorry, it was too good to miss Quote: Originally Posted by cjp  We both made a mistake here. I swapped Ma and Mb (already fixed that in my post) You incorrectly placed minus signs in front of dx and dy From your equations, I assumed that 'A' was the object undergoing acceleration. That is, if the acceleration is proportional to the mass of body B (assuming that Mb is the mass of body b, of course) then my convention is correct. Nobody made mistakes, here. Also, since Gravitation is a central force field, the usual _convention_ is to write r = ro - R, where ro is the position of the object undergoing acceleration and R is the gravity source, so as to explicitly state the minus sign, which is an useful reminder. Of course, it is just a convention. Quote: You are a mathematician, aren't you? Not really, engineer. Does that still qualifies for nerdity? I must admit that I loved the parts about physics and calculus. Quote: Not much more complicated, but it uses trigonometry, while I use vector calculus. I prefer (cartesian) vector calculus, because it doesn't have as many nasty singularities.... Good point. I completely agree. Quote: I just tried your version of the code and it works just fine. I'm not sure how you got an exponent of 3 to get rid of the need for the angle. Because the force, hence the acceleration, has to be proportional to the inverse of the square of the distance between the bodies. Since the distance magnitude "r" is the norm of the distance vector (dx,dy), the norm of the vector (dx,dy)/r^3 is Code: `|| (dx,dy)/r^3 || = || (dx,dy) || / r^3 = r / r^3 = 1 / r^2` I hope it is clear. Related, computing the force that acts on B from A and then doing the same for the force that acts on A from B is a waste of resources. You can compute an antisymmetrical force matrix and then easily apply it on each body.
 04-29-2009, 09:04 PM #14 cr1 Promoting vegetables in space All right here's some of the progress so far (after putting this project on hold for so many months...) Basically there's a heavy (as in about 10e13kg) planet in the middle and two 1kg rocks orbiting it. Should the trajectories look like that normally? They spiral inwards until they get VERY close to the center of the big planet, but because there was no collision detection here they basically had near-infinite force acting on them so both 1kg rocks got ejected. This simulation only uses vector calculations and the equations "F = GMm/r^2" and "F = ma". Timesteps are not really implemented, runs on 30fps. Last edited by cr1; 04-29-2009 at 09:41 PM.
 04-29-2009, 11:42 PM #15 tblaxland Webmaster Quote: Originally Posted by cr1  Should the trajectories look like that normally? They spiral inwards until they get VERY close to the center of the big planet, but because there was no collision detection here they basically had near-infinite force acting on them so both 1kg rocks got ejected. This simulation only uses vector calculations and the equations "F = GMm/r^2" and "F = ma". Timesteps are not really implemented, runs on 30fps. Do you mean you are running fixed interval (sim time) timesteps? You do not have any sort of non-spherical gravity model, so the trajectories should not degrade like that. Looks like an integration problem of some sort.

 Posting Rules BB code is On Smilies are On [IMG] code is On HTML code is Off You may not post new threads You may not post replies You may not post attachments You may not edit your posts
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home Orbiter-Forum.com     Announcements     Meets & Greets Orbiter Space Flight Simulator     Orbiter Web Forum         OFMM         Orbiter Forum Space Station III         Simpit Forum     General Questions & Help     MFD Questions & Help     Hardware & Software Help     Tutorials & Challenges     Orbiter SDK     Orbiter Visualization Project » Orbiter Project Orbiter Addons     OrbitHangar Addons & Comments     Addons     Addon Development     Addon Requests     Addon Support & Bugs         Addon Developer Forums Far Side of the Moon     Spaceflight News     Math & Physics     Astronomy & the Night Sky     Backyard Rocketry     Brighton Lounge     International Forum

All times are GMT. The time now is 09:37 PM.