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
00058 h = sqrt(-log(drand48()*MAX_WIND_SPEED));
00059 h *= (cos(drand48() * 2 * M_PI) + 1);
00060 speed = h;
00061
00062
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
00136 }
00137 }
00138 for (i=0; i<NET_HEIGHT; i+=2) {
00139 for (j=0; j<NET_WIDTH; j+=2) {
00140
00141 if (i == 0)
00142 tmp = NULL;
00143 else
00144 tmp = sectors[i-2][j];
00145
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
00152 sectors[i][j]->set_neighbour(SOUTH, tmp);
00153 if (j == 0)
00154 tmp = NULL;
00155 else
00156 tmp = sectors[i][j-2];
00157
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
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
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
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
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