#include <assert.h> #include <math.h> #include <stdio.h> #include "growingaxonhead.h" #include "growinggrid.h" #include "growingaxonlist.h" #include "growingcell.h" CGrowing_Axon_Head::CGrowing_Axon_Head( C3dpoint ipos, CGrowing_Axon_Cell *ihome, int idistance_to_home, int ifollowing_substance_number ) { pos=ipos; home=ihome; distance_to_home=idistance_to_home; assert(ifollowing_substance_number >=0); assert(ifollowing_substance_number < NR_OF_SUBSTANCES_TO_FOLLOW); following_substance_number=ifollowing_substance_number; inactive_turns=0; still_growing=true; }; CGrowing_Axon_Head::~CGrowing_Axon_Head() { // nothing to be done }; bool CGrowing_Axon_Head::grow_coordinate( CGrowing_Grid &grid, CGrowing_Axon_List *list, float relative_conc, float abs_conc, int x, int y, int z ) { assert(x >= 0); assert(x < CUBE_SIZE); assert(y >= 0); assert(y < CUBE_SIZE); assert(z >= 0); assert(z < CUBE_SIZE); assert(relative_conc != -1); float free_adjacent = ( ((x < CUBE_SIZE-1) && ( ! grid.get_occupied(x+1, y , z ))) ? 1 : 0 ) + ( ((x > 0 ) && ( ! grid.get_occupied(x-1, y , z ))) ? 1 : 0 ) + ( ((y < CUBE_SIZE-1) && ( ! grid.get_occupied(x , y+1, z ))) ? 1 : 0 ) + ( ((y > 0 ) && ( ! grid.get_occupied(x , y-1, z ))) ? 1 : 0 ) + ( ((z < CUBE_SIZE-1) && ( ! grid.get_occupied(x , y , z+1))) ? 1 : 0 ) + ( ((z > 0 ) && ( ! grid.get_occupied(x , y , z-1))) ? 1 : 0 ); float tmp; if ( (!grid.get_occupied( x,y,z )) && ( (relative_conc * free_adjacent / 5.0 * ( (tmp=1.7 - 1 / pow(2,abs_conc) ) > 1 ? 1 : tmp ) ) > drand48() ) ) { grid.set_occupied(x,y,z); list->insert( new CGrowing_Axon_Head( C3dpoint( x,y,z ), home, distance_to_home+1, following_substance_number ) ); //printf("."); return true; }; return false; }; int CGrowing_Axon_Head::grow( CGrowing_Grid &grid, CGrowing_Axon_List *list ) { bool grown_this_turn=false; if (still_growing) { if ( (following_substance_number != NR_OF_SUBSTANCES_TO_FOLLOW) && ( grid.get_concentration( pos.x(), pos.y(), pos.z(), home->get_substance_from_substances_to_follow(following_substance_number) ) > home->get_threshold_from_substances_to_follow(following_substance_number) ) ) following_substance_number++; if (following_substance_number >= NR_OF_SUBSTANCES_TO_FOLLOW) still_growing=false; else { float relative_concs[6]; //6 neighbours F,B,L,R,A,U if ( pos.x() > 0 ) relative_concs[0] = grid.get_concentration( pos.x()-1, pos.y(), pos.z(), home->get_substance_from_substances_to_follow(following_substance_number) ); else relative_concs[0] = -1; if ( pos.x() < CUBE_SIZE-1 ) relative_concs[1] = grid.get_concentration( pos.x()+1, pos.y(), pos.z(), home->get_substance_from_substances_to_follow(following_substance_number) ); else relative_concs[1] = -1; if ( pos.y() > 0 ) relative_concs[2] = grid.get_concentration( pos.x(), pos.y()-1, pos.z(), home->get_substance_from_substances_to_follow(following_substance_number) ); else relative_concs[2] = -1; if ( pos.y() < CUBE_SIZE-1 ) relative_concs[3] = grid.get_concentration( pos.x(), pos.y()+1, pos.z(), home->get_substance_from_substances_to_follow(following_substance_number) ); else relative_concs[3] = -1; if ( pos.z() > 0 ) relative_concs[4] = grid.get_concentration( pos.x(), pos.y(), pos.z()-1, home->get_substance_from_substances_to_follow(following_substance_number) ); else relative_concs[4] = -1; if ( pos.z() < CUBE_SIZE-1 ) relative_concs[5] = grid.get_concentration( pos.x(), pos.y(), pos.z()+1, home->get_substance_from_substances_to_follow(following_substance_number) ); else relative_concs[5] = -1; float abs_conc=0; for(int i=0; i<6; i++) if ( relative_concs[i] > -1 ) abs_conc += relative_concs[i]; float min_conc=100000; // sollte passen for(int i=0; i<6; i++) if ( (relative_concs[i] > -1) && (relative_concs[i] < min_conc) ) min_conc = relative_concs[i]; assert(min_conc!=100000); for(int i=0; i<6; i++) if ( relative_concs[i] > -1 ) relative_concs[i] -= min_conc; for(int i=0; i<6; i++) if ( relative_concs[i] > -1 ) relative_concs[i] = pow(relative_concs[i],home->get_hairiness()); // relative_concs[i] = pow(relative_concs[i],); float sum_conc=0; for(int i=0; i<6; i++) if ( relative_concs[i] > -1 ) sum_conc += relative_concs[i]; for(int i=0; i<6; i++) if ( relative_concs[i] > -1 ) relative_concs[i] = relative_concs[i] / sum_conc; if ( pos.x() > 0 ) if (grow_coordinate(grid, list, relative_concs[0], abs_conc, pos.x()-1, pos.y() , pos.z() )) grown_this_turn = true; if ( pos.x() < CUBE_SIZE-1 ) if (grow_coordinate(grid, list, relative_concs[1], abs_conc, pos.x()+1, pos.y() , pos.z() )) grown_this_turn = true; if ( pos.y() > 0 ) if (grow_coordinate(grid, list, relative_concs[2], abs_conc, pos.x() , pos.y()-1, pos.z() )) grown_this_turn = true; if ( pos.y() < CUBE_SIZE-1 ) if (grow_coordinate(grid, list, relative_concs[3], abs_conc, pos.x() , pos.y()+1, pos.z() )) grown_this_turn = true; if ( pos.z() > 0 ) if (grow_coordinate(grid, list, relative_concs[4], abs_conc, pos.x() , pos.y() , pos.z()-1)) grown_this_turn = true; if ( pos.z() < CUBE_SIZE-1 ) if (grow_coordinate(grid, list, relative_concs[5], abs_conc, pos.x() , pos.y() , pos.z()+1)) grown_this_turn = true; }; // if (grown_this_turn) { // printf("."); // }; // printf("\n"); if (!grown_this_turn) if (++inactive_turns >= home->get_max_inactive_turns() ) still_growing=false; }; if (grown_this_turn) return 1; //magic number alarm, nur temporaer if (still_growing) return -1; return 0; }; bool CGrowing_Axon_Head::get_still_growing() { return still_growing; }; CGrowing_Axon_Cell *CGrowing_Axon_Head::get_home() { return home; }; int CGrowing_Axon_Head::get_home_number() { return home->get_number(); }; int CGrowing_Axon_Head::get_distance_to_home() { return distance_to_home; }; float CGrowing_Axon_Head::get_distance_to_position( C3dpoint spos ) { return sqrt(pow(pos.x()-spos.x(),2) + pow(pos.y()-spos.y(),2) + pow(pos.z()-spos.z(),2)); };