Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

wind.cpp

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <math.h>
00003 #include <stdlib.h>
00004 
00005 #define DEBUG(msg) \
00006   fprintf(stderr, "%s\n", msg);
00007 
00008 #include "wind.h"
00009 
00010 
00011 FNode::FNode(unsigned char xx, unsigned char yy) : SNode(xx, yy) {
00012   
00013 
00014 SNode::SNode(unsigned char xx, unsigned char yy) {
00015   x = xx;
00016   y = yy;
00017   stage = LONELY;
00018   north = south = west = east = northwest = northeast = NULL; 
00019     southwest = southeast = NULL;
00020   speed = 0.0f;
00021   heading = 0.0f;
00022   last_h = -1;
00023 }
00024 
00025 void SNode::set_neighbour(char dir, SNode* other) {
00026   switch(dir) {
00027     case NORTH:
00028       north = other;
00029       break;
00030     case SOUTH:
00031       south = other;
00032       break;
00033     case EAST:
00034       east = other;
00035       break;
00036     case WEST:
00037       west = other;
00038       break;
00039     case NORTHEAST:
00040       northeast = other;
00041       break;
00042     case NORTHWEST:
00043       northwest = other;
00044       break;
00045     case SOUTHWEST:
00046       southwest = other;
00047       break;
00048     case SOUTHEAST:
00049       southeast = other;
00050       break;
00051   }
00052 }
00053 
00054 void SNode::gen_random() {
00055   float h;
00056 
00057   // nearly gaussian distribution (always positive)
00058   h = sqrt(-log(drand48()*MAX_WIND_SPEED));
00059   h *= (cos(drand48() * 2 * M_PI) + 1);
00060   speed = h;
00061   
00062   // and an even distribution
00063   do {
00064     h = (360.0f*rand()/(RAND_MAX+1.0));
00065   }
00066   while (is_forbidden(h));
00067   heading = h;
00068   stage = READY;
00069 }
00070   
00071 
00072 bool SNode::is_forbidden(float angle) {
00073   for (int i=0; i<last_h; i++) {
00074     if (fabs(forbidden_headings[i] - angle) <= 2 * WIND_CONE_DELTA)
00075       return 1;
00076   }
00077   return 0;
00078 }
00079 
00080 void SNode::update_forbidden() {
00081   last_h = -1;
00082   float tmp;
00083   if (north != NULL) {
00084     if (*north->get_stage() >= EMPTY) {
00085       tmp = *north->get_wind_heading();
00086       if ((tmp >= 175.0f) && (tmp <= 185.0f)) {
00087         tmp -= 180.0f;
00088         forbidden_headings[++last_h] = tmp;
00089       }
00090     }
00091   }
00092   if (south != NULL) {
00093     if (*south->get_stage() >= EMPTY) {
00094       tmp = *south->get_wind_heading();
00095       if ((tmp >= 355.0f) && (tmp <= 5.0f)) {
00096         tmp -= 180.0f;
00097         forbidden_headings[++last_h] = tmp;
00098       }
00099     }
00100   }
00101   if (west != NULL) {
00102     if (*west->get_stage() >= EMPTY) {
00103       tmp = *west->get_wind_heading();
00104       if ((tmp >= 85.0f) && (tmp <= 95.0f)) {
00105         tmp -= 180.0f;
00106         forbidden_headings[++last_h] = tmp;
00107       }
00108     }
00109   }
00110   if (east != NULL) {
00111     if (*east->get_stage() >= EMPTY) {
00112       tmp = *east->get_wind_heading();
00113       if ((tmp >= 265.0f) && (tmp <= 275.0f)) {
00114         tmp -= 180.0f;
00115         forbidden_headings[++last_h] = tmp;
00116       }
00117     }
00118   }
00119 }
00120 
00121 
00122 SNet::SNet() {
00123   DEBUG("overall wind network started");
00124   clg();
00125   chg();
00126   initial_rn();
00127 }
00128 
00129 void SNet::clg() {
00130   int i,j;
00131   SNode* tmp;
00132   for (i=0; i<NET_HEIGHT; i+=2) {
00133     for (j=0; j<NET_WIDTH; j+=2) {
00134       sectors[i][j] = new SNode((unsigned char) j, (unsigned char)i);
00135      // printf("node %i %i: %p\n", i, j, sectors[i][j]);
00136     }
00137   }
00138   for (i=0; i<NET_HEIGHT; i+=2) {
00139     for (j=0; j<NET_WIDTH; j+=2) {
00140       //printf("node %i %i ", i, j);
00141       if (i == 0)
00142         tmp = NULL;
00143       else
00144         tmp = sectors[i-2][j];
00145       //printf("north: %p ", tmp);
00146       sectors[i][j]->set_neighbour(NORTH, tmp);
00147       if (i == NET_HEIGHT - 1)
00148         tmp = NULL;
00149       else
00150         tmp = sectors[i+2][j];
00151       //printf("south: %p ", tmp);
00152       sectors[i][j]->set_neighbour(SOUTH, tmp);
00153       if (j == 0)
00154         tmp = NULL;
00155       else
00156         tmp = sectors[i][j-2];
00157       //printf("west: %p ", tmp);
00158       sectors[i][j]->set_neighbour(WEST, tmp);
00159       if (j == NET_WIDTH - 1)
00160         tmp = NULL;
00161       else
00162         tmp = sectors[i][j+2];
00163       //printf("east: %p \n", tmp);
00164       sectors[i][j]->set_neighbour(EAST, tmp);
00165       if (i == 0 || j == 0)
00166         tmp = NULL;
00167       else 
00168         tmp = sectors[i-2][j-2];
00169       //printf("north: %p ", tmp);
00170       sectors[i][j]->set_neighbour(NORTHWEST, tmp);
00171       if (i == NET_HEIGHT - 1 || j == 0)
00172         tmp = NULL;
00173       else
00174         tmp = sectors[i+2][j-2];
00175       //printf("south: %p ", tmp);
00176       sectors[i][j]->set_neighbour(SOUTHWEST, tmp);
00177       if (i == 0 || j == NET_WIDTH - 1 )
00178         tmp = NULL;
00179       else
00180         tmp = sectors[i-2][j+2];
00181       //printf("west: %p ", tmp);
00182       sectors[i][j]->set_neighbour(NORTHEAST, tmp);
00183       if (i == NET_HEIGHT -1 || j == NET_WIDTH - 1)
00184         tmp = NULL;
00185       else
00186         tmp = sectors[i+2][j+2];
00187       sectors[i][j]->set_neighbour(SOUTHEAST, tmp);
00188       sectors[i][j]->set_empty();
00189     }
00190   }
00191 }
00192 
00193 void SNet::chg() {
00194   for (i=0; i<NET_HEIGHT; i++) {
00195     if (i % 2 == 0)
00196       next;
00197     for (j=0; j<NET_WIDTH; j++) {
00198       if (j % 2 == 0)
00199         next;
00200       sectors[i][j] = new FNode((unsigned char)j, (unsigned char) i);
00201     }
00202   }
00203 }
00204 
00205 void SNet::initial_rn() {
00206   int i,j;
00207   for (i=0; i<NET_HEIGHT; i+=2) {
00208     for (j=0; j<NET_WIDTH; j+=2) {
00209       if (!(j==i==0)) 
00210         sectors[i][j]->update_forbidden();
00211       sectors[i][j]->gen_random();
00212     }
00213   }
00214 }
00215 
00216 SNet::~SNet() {
00217   int i,j;
00218   for (i=0; i<NET_HEIGHT; i++) {
00219     for (j=0; j<NET_WIDTH; j++) {
00220       if (sectors[i][j] != NULL)
00221         delete sectors[i][j];
00222     }
00223   }
00224 }
00225 

Generated on Sat Jul 12 04:29:21 2003 for glPirates by doxygen 1.3.2