GRASS Programmer's Manual
6.4.1(2011)
|
00001 00017 #include <stdlib.h> 00018 #include <math.h> 00019 #include <grass/Vect.h> 00020 #include <grass/glocale.h> 00021 00022 static double dist_squared(double, double, double, double); 00023 00041 int 00042 dig_node_add_line(struct Plus_head *plus, int nodeid, int lineid, 00043 struct line_pnts *points, int type) 00044 { 00045 register int i, j, nlines; 00046 float angle; 00047 int ret; 00048 P_NODE *node; 00049 00050 G_debug(3, "dig_node_add_line(): node = %d line = %d", nodeid, lineid); 00051 00052 node = plus->Node[nodeid]; 00053 nlines = node->n_lines; 00054 00055 /* reallocate memory */ 00056 ret = dig_node_alloc_line(node, 1); 00057 if (ret == -1) 00058 return -1; 00059 00060 if (type & GV_LINES) { 00061 if (lineid < 0) 00062 angle = dig_calc_end_angle(points, 0); 00063 else 00064 angle = dig_calc_begin_angle(points, 0); 00065 } 00066 else { 00067 angle = -9.; 00068 } 00069 G_debug(3, " angle = %f", angle); 00070 00071 /* make sure the new angle is less than the empty space at end */ 00072 node->angles[nlines] = 999.; 00073 00074 for (i = 0; i <= nlines; i++) { /* alloced for 1 more */ 00075 if (angle < node->angles[i]) { 00076 /* make room for insertion */ 00077 for (j = nlines - 1; j >= i; j--) { 00078 node->angles[j + 1] = node->angles[j]; 00079 node->lines[j + 1] = node->lines[j]; 00080 } 00081 node->angles[i] = angle; 00082 node->lines[i] = lineid; 00083 break; 00084 } 00085 } 00086 00087 node->n_lines++; 00088 00089 G_debug(3, 00090 "dig_node_add_line(): line %d added position %d n_lines: %d angle %f", 00091 lineid, i, node->n_lines, angle); 00092 00093 return ((int)node->n_lines); 00094 } 00095 00096 00106 int dig_add_node(struct Plus_head *plus, double x, double y, double z) 00107 { 00108 int nnum; 00109 P_NODE *node; 00110 00111 /* First look if we have space in array of pointers to nodes 00112 * and reallocate if necessary */ 00113 G_debug(3, "dig_add_node(): n_nodes = %d, alloc_nodes = %d", 00114 plus->n_nodes, plus->alloc_nodes); 00115 if (plus->n_nodes >= plus->alloc_nodes) { /* array is full */ 00116 if (dig_alloc_nodes(plus, 1000) == -1) 00117 return -1; 00118 } 00119 00120 /* allocate node structure */ 00121 nnum = plus->n_nodes + 1; 00122 00123 plus->Node[nnum] = dig_alloc_node(); 00124 00125 node = plus->Node[nnum]; 00126 node->x = x; 00127 node->y = y; 00128 node->z = z; 00129 00130 dig_spidx_add_node(plus, nnum, x, y, z); 00131 00132 plus->n_nodes++; 00133 00134 G_debug(3, "new node = %d, n_nodes = %d, alloc_nodes = %d", nnum, 00135 plus->n_nodes, plus->alloc_nodes); 00136 00137 return (nnum); 00138 } 00139 00150 int dig_which_node(struct Plus_head *plus, double x, double y, double thresh) 00151 { 00152 register int i; 00153 register int first_time; 00154 register int have_match; 00155 int winner; 00156 double least_dist, dist; 00157 P_NODE *node; 00158 00159 first_time = 1; 00160 have_match = 0; 00161 winner = 0; 00162 least_dist = 0.0; 00163 for (i = 1; i <= plus->n_nodes; i++) { 00164 if (plus->Node[i] == NULL) 00165 continue; 00166 00167 node = plus->Node[i]; 00168 if ((fabs(node->x - x) <= thresh) && (fabs(node->y - y) <= thresh)) { 00169 dist = dist_squared(x, y, node->x, node->y); 00170 if (first_time) { 00171 least_dist = dist; 00172 first_time = 0; 00173 winner = i; 00174 have_match = 1; 00175 } 00176 if (dist < least_dist) { 00177 least_dist = dist; 00178 winner = i; 00179 } 00180 } 00181 } 00182 00183 if (!have_match) 00184 return (-1); 00185 00186 return (winner); 00187 } /* which_node () */ 00188 00202 float dig_node_line_angle(struct Plus_head *plus, int nodeid, int lineid) 00203 { 00204 int i, nlines; 00205 P_NODE *node; 00206 00207 G_debug(3, "dig_node_line_angle: node = %d line = %d", nodeid, lineid); 00208 00209 node = plus->Node[nodeid]; 00210 nlines = node->n_lines; 00211 00212 for (i = 0; i < nlines; i++) { 00213 if (node->lines[i] == lineid) 00214 return (node->angles[i]); 00215 } 00216 00217 G_fatal_error(_("Attempt to read line angle for the line which is not connected to the node: " 00218 "node %d, line %d"), nodeid, lineid); 00219 00220 return 0.0; /* not reached */ 00221 } 00222 00223 static double dist_squared(double x1, double y1, double x2, double y2) 00224 { 00225 double dx, dy; 00226 00227 dx = x1 - x2; 00228 dy = y1 - y2; 00229 return (dx * dx + dy * dy); 00230 }