Quote:
Originally Posted by Vulgar
Like pretend the the player is the sun and that I want earth to revolve around me.
|
The gravitational force works like this:
 = \Gamma \frac{m\cdot M}{r^2} \hat r)
, 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 (i < 10) {
const double last_y = y;
const double last_x = x;
t += dt;
x += dt * x_;
y += 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 << t << ' ' << x << ' ' << y << ' ' << x_ << y_ << '\n';
if (last_y * y < 0) {
++i;
std::cout
<< "x = " << x << "\n"
"y = " << 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 (i < 10) {
const double last_y = y;
t += 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_);
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);
out << t << ' ' << x << ' ' << y << ' ' << x_ << y_ << '\n';
if (last_y * y < 0) {
++i;
std::cout
<< "x = " << x << "\n"
"y = " << 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");
}
}