The experiment went well. I made a simple GUI application with two buttons and applied the laws of the universe to these buttons. They began to gravitate towards each other. I felt very empowered, because even though all I'd done is made a couple of buttons gravitate towards towards each other, I'd also created a universe in my computer. I'm going to share a bare-bones example here which details only the maths behind it all.
There's several things to consider when doing this. First of all, you need a position structure. This should include either X and Y or X, Y and Z:
typedef struct {
double x;
double y;
double z;
} position_t;
This structure represents a position in 2d or 3d space. Then you need a function to calculate the distance between two points. Depending on whether you want your universe to be 2d or 3d, you'll need the appropriate function. I made both anyway, even though my universe was 2d:
double distance2d(position_t *a, position_t *b)
{
return sqrt( pow((b->x - a->x), 2) + pow((b->y - a->y), 2) );
}
double distance3d(position_t *a, position_t *b)
{
double xd, yd, zd;
xd = b->x - a->x;
yd = b->y - a->y;
zd = b->z - a->z;
return sqrt( (xd*xd) + (yd*yd) + (zd*zd) );
}
Square roots are accurate but slow. If you wanted to calculate the distance faster but less accurately, there are other techniques around. Speed wasn't an issue for my experiment.
Next you need a class or structure to represent an object in space. This structure should contain the mass of the object, its position, its acceleration and its velocity. All of these variables are required to calculate the gravitational pull.
typedef struct {
position_t position;
double mass, velocity, acceleration;
} object_t;
int main()
{
position_t a = { 0, 0, 0 };
position_t b = { 10, 10, 10 };
// establish our two bodies
object_t bodya = { a, 999999999, 0, 0 };
object_t bodyb = { a, 444444444, 0, 0 };
// press enter to go forwards, or q to quit
while(getch() != 'q')
{
// calculate the distance between the objects
double d = distance2d(&a, &b);
// calculate the force
double f = (6.67 * pow((1*10), -11)) * (bodya.mass * bodyb.mass)/pow(d, 2);
// calculate the acceleration
bodya.acceleration = f/bodya.mass;
bodyb.acceleration = f/bodyb.mass;
// calculate the velocity
bodya.velocity += bodya.acceleration*1;
bodyb.velocity += bodyb.acceleration*1;
// calculate the position
bodya.position.x += bodya.velocity;
bodyb.position.x += bodyb.velocity;
printf("Body A:\n\tPosition: x(%lf), y(%lf)\n\tVelocity: %f\nBody B:\n\tPosition: x(%lf), y(%lf)\n\tVelocity: %f\n",
bodya.position.x, bodya.position.y, bodya.velocity,
bodyb.position.x, bodyb.position.y, bodyb.velocity);
}
return 0;
}
Are there visuals for the program you wrote for this? I'd like to see.
ReplyDeleteI noted that you accounted for the distance and gravitational force for the mass variable. But I'm a bit worried about the accuracy as you're dealing with exceedingly large values and small decimals.
If you have a program called Xojo (www.xojo.com) then I can give you the basic GUI test I did with the two buttons gravitating toward each other.
ReplyDelete