In article <bt*************@news.t-online.com>
Stephan Aspridis <s.********@t-online.de> writes:
[pretty much entirely snipped]
By not posting a complete program, or even a compile-able snippet,
you make it difficult to give much help. Using the data structures
you posted later, along with the code you included, I came up with
the code below, which appears to work fine. (Note that I just put
in 1.0 for both sun and earth density factors. I also made some
assumptions about get_random().)
The revised version of gronk() -- the function with the troublesome
loop -- has no functional changes except that it does not write on
the one-past-last star[s].planet[p] field. Mostly I just tried
not to repeat variable names over and over and over and over. :-)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct planet_record {
unsigned char core_type[20];
short int ident;
short int orbit_zone;
short int core_ident;
short int number_of_rings;
short int number_of_small_moons;
short int number_of_large_moons;
double orbit_distance;
double orbit_eccentricity;
double orbit_inclination;
double orbit_period;
double orbit_velocity;
double orbit_temperature;
double orbit_temperature_add;
double exosphere_temperature;
double max_temperature;
double min_temperature;
double perihel_add;
double aphel_sub;
double diameter;
double density;
double width;
double mass;
double surface;
double gravity;
double escape_velocity;
double base_temp;
double axial_inclination;
double rotation;
double geosync_orbit;
double horizon_at_eye_level;
double horizon_at_10m;
double horizon_at_100m;
double magnetic_field;
};
struct star_record {
unsigned char type[16];
short int ident;
short int number_of_orbits;
double mass;
double inclination;
double rotation;
double main_sequence_life;
double luminosity;
double main_sequence_radius;
double radius;
double temperature;
double main_sequence_temperature;
double diameter;
double gravity;
double lambda_max;
double period1_2;
double period12_3;
double period12_34;
double period3_4;
double mean_separation1_2;
double mean_separation12_3;
double mean_separation12_34;
double mean_separation3_4;
double eco_rad_inner;
double eco_rad_outer;
double orbit_limit;
#define MAXPLANETS 20
struct planet_record planet[MAXPLANETS];
};
double get_random(double, double);
#define MAXSTARS 2
struct star_record star[2];
void panic(const char *msg) {
fprintf(stderr, "panic: %s\n", msg);
exit(EXIT_FAILURE); /* or abort() */
}
#define SOLDENSITY 1.0
#define EARTHDENSITY 1.0
#ifdef ORIGINAL
/* original poster's code */
void gronk(int s, int orbcount) {
int p, x;
if (s < 0 || s >= MAXSTARS)
panic("star number out of range in gronk()");
if (orbcount < 1 || orbcount > MAXPLANETS)
panic("orbit count limit out of range in gronk()");
star[s].planet[0].orbit_distance =
pow(SOLDENSITY/EARTHDENSITY,1.0/3.0)*
sqrt(star[s].mass)*get_random(50.0,150.0)/100.0;
for (p=0;p<orbcount-1;p++){
x = p+1;
star[s].planet[x].orbit_distance =
star[s].planet[p].orbit_distance*get_random(1250.0,2500.0)/1000.0;
if (star[s].planet[p].orbit_distance>star[s].orbit_limit)
break;
}
star[s].number_of_orbits = p;
}
#else
/* how I would write gronk(): */
void gronk(int s, int orbcount) {
struct star_record *sp;
int p;
double dist;
if (s < 0 || s >= MAXSTARS)
panic("star number out of range in gronk()");
sp = &star[s];
if (orbcount < 0 || orbcount > MAXPLANETS)
panic("orbit count limit out of range in gronk()");
/*
* Calculate distance of innermost planet (if there is to be one).
* Deserves a comment as to why we use the cube root, etc.
*/
dist = pow(SOLDENSITY / EARTHDENSITY, 1.0 / 3.0) *
sqrt(sp->mass) * get_random(0.5, 1.5);
/*
* Place up to orbcount planets in orbit. We have an initial
* distance; successive planets are between 1.25 and 2.5 times
* further than each previous planet. We stop when we have
* filled the requested number, or the next planet to place
* would be beyond the star's orbit limit.
*/
for (p = 0; p < orbcount && dist < sp->orbit_limit; p++) {
sp->planet[p].orbit_distance = dist;
dist *= get_random(1.25, 2.5);
}
sp->number_of_orbits = p;
}
#endif
void setup(int s) {
/* should verify s value */
star[s].mass = 0.689; /* solar mass */
star[s].orbit_limit = 4.286; /* AU */
/* since the rest are not used, I did not initialize them */
}
void show(int s) {
int n;
struct star_record *sp;
/* should verify s value */
sp = &star[s];
printf("stellar characteristics of %d\n", s);
printf(" %-17s : K3 V\n", "type"); /* fake */
printf(" %-17s : %.3f solar mass\n", "mass", sp->mass);
printf("...\n");
printf(" %-17s : %d\n", "number of orbits", sp->number_of_orbits);
printf(" %-17s : %.3f AU\n", "orbital limit", sp->orbit_limit);
printf("...\n");
printf("planets of %d present at:\n", s);
for (n = 0; n < sp->number_of_orbits; n++)
printf(" %.3f AU\n", sp->planet[n].orbit_distance);
}
/* return a number between lo and hi exclusive of hi */
double get_random(double lo, double hi) {
double r;
if (hi <= lo)
panic("bad values to get_random()");
r = (double)rand() / ((double)RAND_MAX + 1.0); /* in [0.0,1.0) */
r *= hi - lo; /* expand to given range */
r += lo;
return r;
}
int main(void) {
srand((unsigned)time(NULL)); /* not quite portable but will serve */
setup(1);
gronk(1, MAXPLANETS);
show(1);
return 0;
}
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.