5
#include <grass/glocale.h>
7
#include "local_proto.h"
10
#define V Region.vertex /* converted vertex list */
11
#define VN Region.vertex_npoints
13
#define P Region.perimeter /* perimeter point list */
14
#define PN Region.perimeter_npoints
16
#define A Region.point
17
#define AN Region.npoints
19
#define extrema(x,y,z) (((x<y)&&(z<y))||((x>y)&&(z>y)))
20
#define non_extrema(x,y,z) (((x<y)&&(y<z))||((x>y)&&(y>z)))
25
int skip; /* boolean */
26
int np; /* perimeter estimate */
27
POINT tmp[MAX_VERTEX]; /* temp vertex list */
35
/* convert alarm area points to data row/col verticies */
36
Menu_msg("Preparing outline...");
38
for (cur = 0; cur < AN; cur++) {
39
temp.y = view_to_row(Region.view, A[cur].y);
40
temp.x = view_to_col(Region.view, A[cur].x);
41
tmp_n = row_to_northing(&(Region.view->cell.head), temp.y, 0.5);
42
tmp_e = col_to_easting(&(Region.view->cell.head), temp.x, 0.5);
43
tmp[cur].y = G_northing_to_row(tmp_n, &Band_cellhd);
44
tmp[cur].x = G_easting_to_col(tmp_e, &Band_cellhd);
47
/* find first edge which is not horizontal */
51
for (cur = 0; cur < AN; prev = cur++)
52
if (tmp[cur].y != tmp[prev].y) {
57
G_warning(_("Absurd polygon."));
61
/* copy tmp to vertex list collapsing adjacent horizontal edges */
65
cur = first; /* stmt not necssary */
68
if (signalflag.interrupt)
79
if ((next = cur + 1) >= AN)
82
skip = ((tmp[prev].y == tmp[cur].y) && (tmp[next].y == tmp[cur].y));
87
/* count points on the perimeter */
91
for (cur = 0; cur < VN; prev = cur++)
92
np += abs(V[prev].y - V[cur].y);
95
/* allocate perimeter list */
97
P = (POINT *) G_malloc(np * sizeof(POINT));
99
G_warning(_("Outlined area is too large."));
103
/* store the perimeter points */
107
for (cur = 0; cur < VN; prev = cur++) {
108
if (signalflag.interrupt)
110
edge(V[prev].x, V[prev].y, V[cur].x, V[cur].y);
114
* now decide which verticies should be included
115
* local extrema are excluded
116
* local non-extrema are included
117
* verticies of horizontal edges which are pseudo-extrema
119
* one vertex of horizontal edges which are pseudo-non-extrema
127
if (signalflag.interrupt)
133
if (extrema(V[prev].y, V[cur].y, V[next].y))
135
else if (non_extrema(V[prev].y, V[cur].y, V[next].y))
141
if (extrema(V[prev].y, V[cur].y, V[next].y))
146
edge_point(V[cur].x, V[cur].y);
154
/* sort the edge points by row and then by col */
156
Menu_msg("Sorting...");
157
qsort(P, (size_t) PN, sizeof(POINT), edge_order);