|
@@ -9,6 +9,11 @@ static struct line_cats *PCats;
|
|
|
static struct line_pnts *PPoints;
|
|
|
static int point_cat = 1;
|
|
|
|
|
|
+static void write_line_forward(struct Map_info *, struct line_pnts *, int, int,
|
|
|
+ int, double, dbDriver *, struct field_info *);
|
|
|
+static void write_line_backward(struct Map_info *, struct line_pnts *, int, int,
|
|
|
+ int, double, dbDriver *, struct field_info *);
|
|
|
+
|
|
|
void write_point(struct Map_info *Out, double x, double y, double z,
|
|
|
int line_cat, double along, dbDriver *driver, struct field_info *Fi)
|
|
|
{
|
|
@@ -57,8 +62,21 @@ void write_point(struct Map_info *Out, double x, double y, double z,
|
|
|
}
|
|
|
|
|
|
void write_line(struct Map_info *Out, struct line_pnts *LPoints, int cat,
|
|
|
- int vertex, int interpolate, double dmax,
|
|
|
- dbDriver *driver, struct field_info *Fi)
|
|
|
+ int vertex, int interpolate, int reverse, double dmax,
|
|
|
+ dbDriver *driver, struct field_info *Fi)
|
|
|
+{
|
|
|
+ if (reverse == 0)
|
|
|
+ write_line_forward(Out, LPoints, cat, vertex, interpolate, dmax,
|
|
|
+ driver, Fi);
|
|
|
+ else
|
|
|
+ write_line_backward(Out, LPoints, cat, vertex, interpolate, dmax,
|
|
|
+ driver, Fi);
|
|
|
+}
|
|
|
+
|
|
|
+static void write_line_forward(struct Map_info *Out, struct line_pnts *LPoints,
|
|
|
+ int cat, int vertex, int interpolate,
|
|
|
+ double dmax, dbDriver *driver,
|
|
|
+ struct field_info *Fi)
|
|
|
{
|
|
|
if (vertex == GV_VERTEX || vertex == GV_NODE) { /* use line vertices */
|
|
|
double along;
|
|
@@ -71,6 +89,8 @@ void write_line(struct Map_info *Out, struct line_pnts *LPoints, int cat,
|
|
|
if (vertex == GV_VERTEX ||
|
|
|
(vertex == GV_NODE &&
|
|
|
(vert == 0 || vert == LPoints->n_points - 1))) {
|
|
|
+ if (vert == LPoints->n_points - 1)
|
|
|
+ along = Vect_line_length(LPoints);
|
|
|
write_point(Out, LPoints->x[vert], LPoints->y[vert],
|
|
|
LPoints->z[vert], cat, along, driver, Fi);
|
|
|
}
|
|
@@ -84,7 +104,7 @@ void write_line(struct Map_info *Out, struct line_pnts *LPoints, int cat,
|
|
|
len = hypot(hypot(dx, dy), dz);
|
|
|
|
|
|
/* interpolate segment */
|
|
|
- if (vertex == GV_VERTEX && interpolate) {
|
|
|
+ if (interpolate && vertex == GV_VERTEX) {
|
|
|
int i, n;
|
|
|
double x, y, z, dlen;
|
|
|
|
|
@@ -143,3 +163,94 @@ void write_line(struct Map_info *Out, struct line_pnts *LPoints, int cat,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+static void write_line_backward(struct Map_info *Out, struct line_pnts *LPoints,
|
|
|
+ int cat, int vertex, int interpolate,
|
|
|
+ double dmax, dbDriver *driver,
|
|
|
+ struct field_info *Fi)
|
|
|
+{
|
|
|
+ if (vertex == GV_VERTEX || vertex == GV_NODE) { /* use line vertices */
|
|
|
+ double along;
|
|
|
+ int vert;
|
|
|
+
|
|
|
+ along = Vect_line_length(LPoints);
|
|
|
+ for (vert = LPoints->n_points - 1; vert >= 0; vert--) {
|
|
|
+ G_debug(3, "vert = %d", vert);
|
|
|
+
|
|
|
+ if (vertex == GV_VERTEX ||
|
|
|
+ (vertex == GV_NODE &&
|
|
|
+ (vert == 0 || vert == LPoints->n_points - 1))) {
|
|
|
+ if (vert == 0)
|
|
|
+ along = 0;
|
|
|
+ write_point(Out, LPoints->x[vert], LPoints->y[vert],
|
|
|
+ LPoints->z[vert], cat, along, driver, Fi);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (vert > 0) {
|
|
|
+ double dx, dy, dz, len;
|
|
|
+
|
|
|
+ dx = LPoints->x[vert - 1] - LPoints->x[vert];
|
|
|
+ dy = LPoints->y[vert - 1] - LPoints->y[vert];
|
|
|
+ dz = LPoints->z[vert - 1] - LPoints->z[vert];
|
|
|
+ len = hypot(hypot(dx, dy), dz);
|
|
|
+
|
|
|
+ /* interpolate segment */
|
|
|
+ if (interpolate && vertex == GV_VERTEX) {
|
|
|
+ int i, n;
|
|
|
+ double x, y, z, dlen;
|
|
|
+
|
|
|
+ if (len > dmax) {
|
|
|
+ n = len / dmax + 1; /* number of segments */
|
|
|
+ dx /= n;
|
|
|
+ dy /= n;
|
|
|
+ dz /= n;
|
|
|
+ dlen = len / n;
|
|
|
+
|
|
|
+ for (i = 1; i < n; i++) {
|
|
|
+ x = LPoints->x[vert] + i * dx;
|
|
|
+ y = LPoints->y[vert] + i * dy;
|
|
|
+ z = LPoints->z[vert] + i * dz;
|
|
|
+
|
|
|
+ write_point(Out, x, y, z, cat, along - i * dlen,
|
|
|
+ driver, Fi);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ along -= len;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else { /* do not use vertices */
|
|
|
+ int i, n;
|
|
|
+ double len, dlen, along, x, y, z;
|
|
|
+
|
|
|
+ len = Vect_line_length(LPoints);
|
|
|
+ n = len / dmax + 1; /* number of segments */
|
|
|
+ dlen = len / n; /* length of segment */
|
|
|
+
|
|
|
+ G_debug(3, "n = %d len = %f dlen = %f", n, len, dlen);
|
|
|
+
|
|
|
+ for (i = 0; i <= n; i++) {
|
|
|
+ if (i > 0 && i < n) {
|
|
|
+ along = len - i * dlen;
|
|
|
+ Vect_point_on_line(LPoints, along, &x, &y, &z, NULL, NULL);
|
|
|
+ }
|
|
|
+ else { /* first and last vertex */
|
|
|
+ if (i == 0) {
|
|
|
+ along = len;
|
|
|
+ x = LPoints->x[LPoints->n_points - 1];
|
|
|
+ y = LPoints->y[LPoints->n_points - 1];
|
|
|
+ z = LPoints->z[LPoints->n_points - 1];
|
|
|
+ }
|
|
|
+ else { /* last */
|
|
|
+ along = 0;
|
|
|
+ x = LPoints->x[0];
|
|
|
+ y = LPoints->y[0];
|
|
|
+ z = LPoints->z[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ G_debug(3, " i = %d along = %f", i, along);
|
|
|
+ write_point(Out, x, y, z, cat, along, driver, Fi);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|