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
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
00072 node->angles[nlines] = 999.;
00073
00074 for (i = 0; i <= nlines; i++) {
00075 if (angle < node->angles[i]) {
00076
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
00112
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) {
00116 if (dig_alloc_nodes(plus, 1000) == -1)
00117 return -1;
00118 }
00119
00120
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 }
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;
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 }