#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));
};