/************************************************************************ * * select_linksB.c in ~/r.spread * * function to select cell links for elliptical spread and to put * the destinated cell of a link in a simple linked list of type * cell_ptrHa. * * The selection rule is: cells in an enlarged spread ellipse * centered at the current spread cell. The apogee is 1 cell plus * the integer number of cells of the ratio of the maximum rate * of spread (ROS) to the base (perpendicular to the max) ROS. * * By Jianping Xu, Rutgers University. * 06/22/93 * *************************************************************************/ #include #include #include #include "costHa.h" #include "cell_ptrHa.h" #include "local_proto.h" #ifndef PI #define PI M_PI #endif #define DATA(map, r, c) (map)[(r) * ncols + (c)] /*#define DEBUG*/ void select_linksB (struct costHa *pres_cell, int least, float comp_dens) { extern CELL *map_max, *map_dir, *map_base; /*for ellipse*/ extern CELL *map_visit; /*for avoiding redundancy*/ extern int BARRIER; extern int nrows, ncols; extern struct cell_ptrHa *front_cell, *rear_cell; float angle; /*that of a link cell to spread cell*/ float dir_angle; /*that of the maximum ROS*/ float cos_dir_angle, sin_dir_angle; float polar_len; /*polar distance of the ellipse*/ float distance; int n=0, s=0, e=0, w=0; /*parameters defining a rectangule*/ int ros_max, ros_base, dir; /*3 params defining an elps*/ int row, col; #ifdef DEBUG printf("\nin select pres(%d,%d) ", pres_cell->row, pres_cell->col); #endif #ifdef DEBUG for ( row=0 ; rowrow, pres_cell->col); ros_base= DATA(map_base,pres_cell->row, pres_cell->col); dir = DATA(map_dir, pres_cell->row, pres_cell->col); dir_angle = dir % 360 * PI / 180; sin_dir_angle = sin(dir_angle); cos_dir_angle = cos(dir_angle); /* identifies a rectangular just enclosing the ellipse, * thus avoiding redundant work in selection */ if (dir_angle >= 7 * PI / 4 || dir_angle < PI / 4) {/*down mainly N*/ n = (ros_max / ros_base - 1) * comp_dens + least; s = least; w = (ros_max / ros_base - 1) * comp_dens + least; e = (ros_max / ros_base - 1) * comp_dens + least; } if (dir_angle >= PI / 4 && dir_angle < 3 * PI / 4) {/*down mainly E*/ n = (ros_max / ros_base - 1) * comp_dens + least; s = (ros_max / ros_base - 1) * comp_dens + least; w = least; e = (ros_max / ros_base - 1) * comp_dens + least; } if (dir_angle >= 3 * PI / 4 && dir_angle < 5 * PI / 4){/*down mainly S*/ n = least; s = (ros_max / ros_base - 1) * comp_dens + least; w = (ros_max / ros_base - 1) * comp_dens + least; e = (ros_max / ros_base - 1) * comp_dens + least; } if (dir_angle >= 5 * PI / 4 && dir_angle < 7 * PI / 4){/*down mainly W*/ n = (ros_max / ros_base - 1) * comp_dens + least; s = (ros_max / ros_base - 1) * comp_dens + least; w = (ros_max / ros_base - 1) * comp_dens + least; e = least; } if (n > least) n--;if (n > least) n--; if (s > least) s--;if (s > least) s--; if (e > least) e--;if (e > least) e--; if (w > least) w--;if (w > least) w--; /* collect cells in the elliptical templet, put into a list */ for (row = pres_cell->row - n; row <= pres_cell->row + s; row++) { if (row < 0 || row >= nrows) /*outside n,s*/ continue; for (col = pres_cell->col - w; col <= pres_cell->col + e; col++) { #ifdef DEBUG printf("(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d\n",row, col,ros_max,ros_base,dir,least,n,s,e,w,DATA(map_base,row,col),BARRIER); #endif if (col < 0 || col >= ncols) /*outside e,w*/ continue; #ifdef DEBUG printf("(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d\n",row, col,ros_max,ros_base,dir,least,n,s,e,w,DATA(map_base,row,col),BARRIER); #endif if (row == pres_cell->row && col == pres_cell->col) continue; /*spread cell*/ #ifdef DEBUG printf("(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d\n",row, col,ros_max,ros_base,dir,least,n,s,e,w,DATA(map_base,row,col),BARRIER); #endif if (DATA(map_visit,row,col)) /*visited?*/ continue; #ifdef DEBUG printf("(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d\n",row, col,ros_max,ros_base,dir,least,n,s,e,w,DATA(map_base,row,col),BARRIER); #endif if (DATA(map_base,row,col)==BARRIER) /*barriers*/ continue; #ifdef DEBUG printf("(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d\n",row, col,ros_max,ros_base,dir,least,n,s,e,w); #endif angle = atan2((double) (col - pres_cell->col), (double) (pres_cell->row - row)); /*the polar (square) distance of enlarged ellipse*/ polar_len = (1 / (1 - (1 - ros_base / (float) ros_max) * cos(angle - dir_angle))) * (1 / (1 - (1 - ros_base / (float) ros_max) * cos(angle - dir_angle))) + 2*least*least; /*the (square) distance to this cell*/ distance = (float) (row - pres_cell->row) * (row - pres_cell->row) + (col - pres_cell->col) * (col - pres_cell->col); /*applies the selection rule*/ if (distance > polar_len) continue; insert2Ha(&front_cell, &rear_cell, (float) angle, row, col); } } }