123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- /************************************************************************
- *
- * 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 <stdio.h>
- #include <math.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #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; row < nrows; row++) {
- printf("\nrow %d: ", row);
- for (col = 0; col < ncols; col++)
- printf("%d ", DATA(map_base, row, col));
- }
- #endif
- ros_max = DATA(map_max, pres_cell->row, 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++) {
- G_debug(4,
- "(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d",
- row, col, ros_max, ros_base, dir, least, n, s, e, w,
- DATA(map_base, row, col), BARRIER);
- if (col < 0 || col >= ncols) /*outside e,w */
- continue;
- G_debug(4,
- "(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d",
- row, col, ros_max, ros_base, dir, least, n, s, e, w,
- DATA(map_base, row, col), BARRIER);
- if (row == pres_cell->row && col == pres_cell->col)
- continue; /*spread cell */
- G_debug(4,
- "(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d",
- row, col, ros_max, ros_base, dir, least, n, s, e, w,
- DATA(map_base, row, col), BARRIER);
- if (DATA(map_visit, row, col)) /*visited? */
- continue;
- G_debug(4,
- "(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d base=%d BARRIER=%d",
- row, col, ros_max, ros_base, dir, least, n, s, e, w,
- DATA(map_base, row, col), BARRIER);
- if (DATA(map_base, row, col) == BARRIER) /*barriers */
- continue;
- G_debug(4,
- "(%d, %d) max=%d base=%d dir=%d least=%d n=%d s=%d e=%d w=%d",
- row, col, ros_max, ros_base, dir, least, n, s, e, w);
- 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);
- }
- }
- }
|