home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1989
/
09
/
king.lst
< prev
next >
Wrap
File List
|
1989-07-27
|
6KB
|
311 lines
_FORCED-BASED SIMULATIONS_
by Todd King
[LISTING ONE]
/*-------------------------------------
Basic object classes and method
definitions for simulation software
File: simul.hpp
Todd King
----------------------------------------*/
#include <stream.hpp>
#include <disp.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include <math.h>
#include "simconst.h"
#define ESC 27
#define MAX_BODY_POOL 100
typedef struct VECTOR_2D {
double x, y;
};
class BODY {
VECTOR_2D world;
VECTOR_2D velocity;
double mass;
double gmass;
char icon;
public:
BODY();
set_mass(double m);
set_velocity(double x, double y);
set_position(double x, double y);
apply_force(VECTOR_2D from, double amount);
VECTOR_2D position();
double get_gmass();
update();
set_icon(char c);
};
/* Distance and time units are converted to screen units and ticks */
BODY::set_mass(double m) {
double pow();
mass = m;
gmass = G * m;
};
BODY::set_velocity(double x, double y) {
velocity.x = x;
velocity.y = y;
};
BODY::set_position(double x, double y) {
world.x = x;
world.y = y;
};
BODY::apply_force(VECTOR_2D from, double gmass) {
VECTOR_2D d;
double rs;
double v;
double r;
d.x = world.x - from.x;
d.y = world.y - from.y;
rs = (d.x * d.x) + (d.y * d.y);
if(rs != 0.0) { // there's a seperation
r = sqrt(rs);
v = (gmass / rs) * SECS_PER_TIC;
velocity.x += v * d.x / r;
velocity.y += v * d.y / r;
}
};
BODY::BODY() {
world.x = 0;
world.y = 0;
velocity.x = 0;
velocity.y = 0;
icon = '*';
};
VECTOR_2D BODY::position() {
VECTOR_2D vec;
vec.x = world.x;
vec.y = world.y;
return(vec);
};
double BODY::get_gmass() {
return(gmass);
}
BODY::set_icon(char c) { icon = c; }
class UNIVERSE {
unsigned int body_cnt;
BODY *body_pool[MAX_BODY_POOL];
public:
UNIVERSE();
service(BODY *bptr);
big_bang();
};
UNIVERSE::UNIVERSE() {
body_cnt = 0;
};
UNIVERSE::service(BODY *bptr) {
if(body_cnt >= MAX_BODY_POOL) return(0);
body_pool[body_cnt] = bptr;
body_cnt++;
};
UNIVERSE::big_bang() {
int i, j;
init_screen();
print_message(" Press ESC to stop.");
for(;;) {
print_tick();
if(kbhit()) {
switch(getch())
{
case ESC:
return(0);
}
}
sleep(0.1);
/* Let each body influence all others */
for(i = 0; i < body_cnt; i++) {
for(j = 0; j < body_cnt; j++) {
if(j == i) continue; // don't apply force to self
body_pool[i]->apply_force(body_pool[j]->position(),
body_pool[j]->get_gmass());
}
}
/* Display all bodies */
for(i = 0; i < body_cnt; i++) {
body_pool[i]->update();
}
}
deinit_screen();
};
sleep(double seconds) {
time_t ltime1, ltime2;
time(<ime1);
time(<ime2);
while(difftime(ltime1, ltime2) < seconds) {
time(<ime2);
}
}
[LISTING TWO]
/*--------------------------------------------
Methods which are related to screen I/O.
File: simulscr.hpp
Todd King
----------------------------------------------*/
#include "simconst.h"
#define DISPLAY_Y 24
#define DISPLAY_X 80
BODY::update() {
extern VECTOR_2D Extent;
VECTOR_2D screen;
screen.x = DISPLAY_X * (world.x / EXTENT_X);
screen.y = DISPLAY_Y * (world.y / EXTENT_Y);
if( (screen.x < DISPLAY_X && screen.x >= 0.0) &&
(screen.y < DISPLAY_Y && screen.y >= 0.0) ) {
disp_move(DISPLAY_Y - (int) screen.y, (int) screen.x);
disp_printf(" ");
}
world.x += velocity.x * SECS_PER_TIC;
world.y += velocity.y * SECS_PER_TIC;
screen.x = DISPLAY_X * (world.x / EXTENT_X);
screen.y = DISPLAY_Y * (world.y / EXTENT_Y);
if( (screen.x < DISPLAY_X && screen.x >= 0.0) &&
(screen.y < DISPLAY_Y && screen.y >= 0.0) ) {
disp_move(DISPLAY_Y - (int) screen.y, (int) screen.x);
disp_printf("%c", icon);
}
disp_move(0,0);
};
init_screen() {
disp_open();
disp_move(0, 0);
disp_eeop();
}
deinit_screen() {
disp_close();
}
print_tick() {
static unsigned int Tick = 0;
disp_move(0, 0);
disp_printf("Tick: %u", Tick);
Tick++;
}
print_message(char mesg[]) {
disp_move(24,0);
disp_printf(mesg);
}
[LISTING FOUR]
/*------------------------------------------------
Simulation of what would happen if a planet
about twice the size of the Moon passed
close to the earth within the Moon's orbit.
Todd King
--------------------------------------------------*/
#include "simul.hpp"
#include "simulscr.hpp"
main() {
BODY earth;
BODY moon;
BODY planet_x;
UNIVERSE universe;
earth.set_mass(5.98e24);
earth.set_position(5.0e8, 5.0e8);
earth.set_icon('E');
moon.set_mass(7.36e22);
moon.set_position(5.0e8, 8.8e8);
moon.set_icon('M');
moon.set_velocity(-1020.0, 0.0);
planet_x.set_mass(14.8e22);
planet_x.set_position(1.0, 1.0e4);
planet_x.set_icon('X');
planet_x.set_velocity(1800, 2000);
universe.service(&earth);
universe.service(&moon);
universe.service(&planet_x);
universe.big_bang();
}
[LISTING FOUR]
/*-----------------------------------------------------
Various constants which affect the simulation
system. Units are in meters, seconds and Kilograms.
File: simconst.h
Todd King
-------------------------------------------------------*/
#define G -6.67e-11 /* Gravitational constant */
#define SECS_PER_TIC 86400 /* One day */
#define EXTENT_X 10e8 /* Width of displayed universe */
#define EXTENT_Y 10e8 /* Hieght of displayed universe */
[EXAMPLE 1]
/*-----------------------------------------------
Simulates the orbital dynamics of the Earth
and Moon.
Todd King
-------------------------------------------------*/
#include "simul.hpp"
#include "simulscr.hpp"
main() {
BODY earth;
BODY moon;
UNIVERSE universe;
earth.set_mass(5.98e24);
earth.set_position(5.0e8, 5.0e8);
earth.set_icon('E');
moon.set_mass(7.36e22);
moon.set_position(5.0e8, 8.8e8);
moon.set_icon('M');
moon.set_velocity(-1020.0, 0.0);
universe.service(&earth);
universe.service(&moon);
universe.big_bang();
}