Graal Forums  

Go Back   Graal Forums > Development Forums > NPC Scripting
FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
  #4  
Old 12-11-2008, 04:17 PM
Loriel Loriel is offline
Somewhat rusty
Loriel's Avatar
Join Date: Mar 2001
Posts: 5,059
Loriel is a name known to allLoriel is a name known to allLoriel is a name known to allLoriel is a name known to all
Quote:
Originally Posted by Vulgar View Post
Like pretend the the player is the sun and that I want earth to revolve around me.
The gravitational force works like this: , with the gravitational constant , the masses and of the two bodies and the distance between them.

For a stable orbit you need to achieve a constant state of freefall, where the gravitation only impacts the direction of the orbitting body's velocity, ie it acts as the centripetal force . It has to be orthogonal to the direction of the velocity of the body anyway, so we can examine this as a one-dimensional problem.

We obtain . You basically just need to write up an engine that applies the gravitational force to the velocity each timestep , then solve for to determine the required speed for the orbitting body at the desired distance after inserting the masses of both.

Here is a sample implementation of two numerical approaches to solving differential equations, perhaps it could help you:

PHP Code:
#include <iostream>
#include <ostream>
#include <fstream>
#include <cmath>

#include "common.hpp"

int main() {
  
using std::sqrt;
  
using prog::pow;

  
// Euler
  
{
    
double x 1;
    
double y 0;
    
double x_ 0;
    
double y_ 0.75;
    
double t  0;
    const 
double dt 1.0/100;
    
int i 0;
    
std::ofstream out("euler_log");

    while (
10) {
      const 
double last_y y;
      const 
double last_x x;

      
+= dt;

      
+= dt x_;
      
+= dt y_;

      
x_ += dt * -1/pow<3>(sqrt(pow<2>(last_x)+pow<2>(last_y))) * last_x;
      
y_ += dt * -1/pow<3>(sqrt(pow<2>(last_x)+pow<2>(last_y))) * last_y;

      
out << << ' ' << << ' ' << << ' ' << x_ << y_ << '\n';
      if (
last_y 0) {
        ++
i;
        
std::cout
         
<< "x   = " << << "\n"
            "y   = " 
<< << "\n"
            "E   = " 
<< ((x_*x_+y_*y_)/2-1/sqrt(pow<2>(x)+pow<2>(y))) << "\n"
            "L_z = " 
<< (x*y_ y*x_) << '\n' << std::endl;
      }

    }
    
system("gnuplot -persist euler_plot");
  }
  
// Runge-Kutta
  
{
    
double x 1;
    
double y 0;
    
double x_ 0;
    
double y_ 0.75;
    
double t  0;
    const 
double dt 1.0/100;
    
int i 0;
    
std::ofstream out("runge-kutta_log");

    while (
10) {
      const 
double last_y y;

      
+= dt;

      const 
double k1_x  x_;
      const 
double k1_y  y_;

      const 
double k1_x_ = -1/pow<3>(sqrt(pow<2>(x)+pow<2>(y)))*x;
      const 
double k1_y_ = -1/pow<3>(sqrt(pow<2>(x)+pow<2>(y)))*y;

      const 
double k2_x  x_ dt/2*k1_x_;
      const 
double k2_y  y_ dt/2*k1_y_;

      const 
double k2_x_ = -1/pow<3>(sqrt(pow<2>(x+dt/2*k1_x)+pow<2>(y+dt/2*k1_y)))*(x+dt/2*k1_x);
      const 
double k2_y_ = -1/pow<3>(sqrt(pow<2>(x+dt/2*k1_x)+pow<2>(y+dt/2*k1_y)))*(y+dt/2*k1_y);

      const 
double k3_x  x_ dt/2*k2_x_;
      const 
double k3_y  y_ dt/2*k2_y_;

      const 
double k3_x_ = -1/pow<3>(sqrt(pow<2>(x+dt/2*k2_x)+pow<2>(y+dt/2*k2_y)))*(x+dt/2*k2_x);
      const 
double k3_y_ = -1/pow<3>(sqrt(pow<2>(x+dt/2*k2_x)+pow<2>(y+dt/2*k2_y)))*(y+dt/2*k2_y);

      const 
double k4_x  x_ dt*k2_x_;
      const 
double k4_y  y_ dt*k2_y_;

      const 
double k4_x_ = -1/pow<3>(sqrt(pow<2>(x+dt*k3_x)+pow<2>(y+dt*k3_y)))*(x+dt*k3_x);
      const 
double k4_y_ = -1/pow<3>(sqrt(pow<2>(x+dt*k3_x)+pow<2>(y+dt*k3_y)))*(y+dt*k3_y);

      
x_ x_ dt/6*(k1_x_+2*k2_x_+2*k3_x_+k4_x_);
      
y_ y_ dt/6*(k1_y_+2*k2_y_+2*k3_y_+k4_y_);

      
dt/6*(k1_x+2*k2_x+2*k3_x+k4_x);
      
dt/6*(k1_y+2*k2_y+2*k3_y+k4_y);


      
out << << ' ' << << ' ' << << ' ' << x_ << y_ << '\n';
      if (
last_y 0) {
        ++
i;
        
std::cout
         
<< "x   = " << << "\n"
            "y   = " 
<< << "\n"
            "E   = " 
<< ((x_*x_+y_*y_)/2-1/sqrt(pow<2>(x)+pow<2>(y))) << "\n"
            "L_z = " 
<< (x*y_ y*x_) << '\n' << std::endl;
      }

    }
    
system("gnuplot -persist runge-kutta_plot");
  }

Reply With Quote
 

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 09:26 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.