35 #include <grass/gis.h>
36 #include <grass/raster.h>
37 #include <grass/display.h>
61 static struct plane pl_left = { -1, 0, 0 };
62 static struct plane pl_rite = { 1, 0, 0 };
63 static struct plane pl_bot = { 0, -1, 0 };
64 static struct plane pl_top = { 0, 1, 0 };
66 static int window_set;
68 #define min(x,y) ((x) < (y) ? (x) : (y))
69 #define max(x,y) ((x) > (y) ? (x) : (y))
71 #define round(x) ((int) floor(0.5 + (x)))
76 static double *xf, *yf;
79 static void alloc_int(
int n)
86 xi = G_realloc(xi, nalloc_i *
sizeof(
int));
87 yi = G_realloc(yi, nalloc_i *
sizeof(
int));
90 static void alloc_float(
int n)
97 xf = G_realloc(xf, nalloc_f *
sizeof(
double));
98 yf = G_realloc(yf, nalloc_f *
sizeof(
double));
101 static void dealloc_float(
const double **
x,
const double **
y,
int release)
117 static int do_filter(
int *x,
int *y,
int n)
121 for (i = 0, j = 1; j <
n; j++) {
122 if (x[j] == x[i] && y[j] == y[i])
134 static void do_round(
const double *x,
const double *y,
int n)
140 for (i = 0; i <
n; i++) {
146 static void do_floor(
const double *x,
const double *y,
int n)
152 for (i = 0; i <
n; i++) {
158 static double dist_plane(
double x,
double y,
const struct plane *p)
160 return x * p->
x + y * p->
y + p->
k;
163 static double interpolate(
double a,
double b,
double ka,
double kb)
165 return (a * kb - b * ka) / (kb - ka);
168 static int clip_plane(
struct vector *a,
struct vector *b,
169 const struct plane *p,
int *clipped)
171 double ka = dist_plane(a->
x, a->
y, p);
172 double kb = dist_plane(b->
x, b->
y, p);
176 if (ka > 0 && kb > 0)
180 if (ka <= 0 && kb <= 0)
200 b->
x = interpolate(a->
x, b->
x, ka, kb);
201 b->
y = interpolate(a->
y, b->
y, ka, kb);
214 if (a->
y < clip.
bot && b->
y < clip.
bot)
216 if (a->
y > clip.
top && b->
y > clip.
top)
219 if (clip_plane(a, b, &pl_left, &clipped))
221 if (clip_plane(a, b, &pl_rite, &clipped))
223 if (clip_plane(a, b, &pl_bot, &clipped))
225 if (clip_plane(a, b, &pl_top, &clipped))
231 static int shift_count(
double dx)
233 return (
int)floor(dx / 360);
236 static double shift_angle(
double dx)
238 return shift_count(dx) * 360;
241 static double coerce(
double x)
249 static int euclidify(
double *x,
const double *y,
int n,
int no_pole)
251 double ux0 = clip.
left;
252 double ux1 = clip.
rite;
259 for (i = 1; i <
n; i++) {
260 if (fabs(y[i]) < 89.9)
261 x[i] = x[i - 1] + coerce(x[i] - x[i - 1]);
267 if (no_pole && fabs(x[n - 1] - x[0]) > 180)
270 lo = -shift_count(ux1 - x0);
271 hi = shift_count(x1 - ux0);
274 for (i = 0; i <
n; i++)
280 static void do_ll_wrap(
const double *x,
const double *y,
int n,
281 void (*func) (
const double *,
const double *,
int))
283 double *xx = G_malloc(n *
sizeof(
double));
286 memcpy(xx, x, n *
sizeof(
double));
287 count = euclidify(xx, y, n, 0);
289 for (i = 0; i <
count; i++) {
294 for (j = 0; j <
n; j++)
320 pl_left.
k = clip.
left;
321 pl_rite.
k = -clip.
rite;
323 pl_top.
k = -clip.
top;
374 static int line_clip(
double x1,
double y1,
double x2,
double y2)
385 clipped = do_clip(&a, &b);
400 static int line_clip_ll(
double ax,
double ay,
double bx,
double by)
402 double ux0 = clip.
left;
403 double ux1 = clip.
rite;
408 bx = ax + coerce(bx - ax);
413 lo = -shift_count(ux1 - x0);
414 hi = shift_count(x1 - ux0);
418 for (i = lo; i <= hi; i++)
419 ret |= line_clip(ax + i * 360, ay, bx + i * 360, by);
432 ret = line_clip_ll(cur.
x, cur.
y, x, y);
434 ret = line_clip(cur.
x, cur.
y, x, y);
444 double ux0 = clip.
left;
452 for (i = j = 0; i <
n; i++) {
457 xx -= shift_angle(x[i] - ux0);
459 if (xx < clip.left || xx > clip.
rite)
461 if (yy < clip.bot || yy > clip.
top)
470 n = do_filter(xi, yi, n);
475 static int cull_polyline_plane(
int *pn,
const double *x,
const double *y,
476 const struct plane *p)
483 double d0 = dist_plane(x0, y0, p);
486 for (i = 0, j = 0; i <
n; i++) {
489 double d1 = dist_plane(x1, y1, p);
493 if (!in0 && in1 && last != prev) {
520 static void polyline_cull(
const double *x,
const double *y,
int n)
524 if (cull_polyline_plane(&n, x, y, &pl_left))
527 dealloc_float(&x, &y, 0);
529 if (cull_polyline_plane(&n, x, y, &pl_rite))
532 dealloc_float(&x, &y, 1);
534 if (cull_polyline_plane(&n, x, y, &pl_bot))
537 dealloc_float(&x, &y, 1);
539 if (cull_polyline_plane(&n, x, y, &pl_top))
542 dealloc_float(&x, &y, 1);
545 n = do_filter(xi, yi, n);
559 do_ll_wrap(x, y, n, polyline_cull);
561 polyline_cull(x, y, n);
564 static void polyline_clip(
const double *x,
const double *y,
int n)
568 for (i = 1; i <
n; i++)
569 line_clip(x[i - 1], y[i - 1], x[i], y[i]);
581 do_ll_wrap(x, y, n, polyline_clip);
583 polyline_clip(x, y, n);
586 static int cull_polygon_plane(
int *pn,
const double *x,
const double *y,
587 const struct plane *p)
594 double d0 = dist_plane(x0, y0, p);
597 for (i = j = 0; i <
n; i++) {
600 double d1 = dist_plane(x1, y1, p);
604 if (!in0 && in1 && last != prev) {
631 static void polygon_cull(
const double *x,
const double *y,
int n)
635 if (cull_polygon_plane(&n, x, y, &pl_left))
638 dealloc_float(&x, &y, 0);
640 if (cull_polygon_plane(&n, x, y, &pl_rite))
643 dealloc_float(&x, &y, 1);
645 if (cull_polygon_plane(&n, x, y, &pl_bot))
648 dealloc_float(&x, &y, 1);
650 if (cull_polygon_plane(&n, x, y, &pl_top))
653 dealloc_float(&x, &y, 1);
656 n = do_filter(xi, yi, n);
667 do_ll_wrap(x, y, n, polygon_cull);
669 polygon_cull(x, y, n);
672 static int clip_polygon_plane(
int *pn,
const double *x,
const double *y,
673 const struct plane *p)
676 double x0 = x[n - 1];
677 double y0 = y[n - 1];
678 double d0 = dist_plane(x0, y0, p);
681 for (i = j = 0; i <
n; i++) {
684 double d1 = dist_plane(x1, y1, p);
690 xf[j] = interpolate(x0, x1, d0, d1);
691 yf[j] = interpolate(y0, y1, d0, d1);
712 static void polygon_clip(
const double *x,
const double *y,
int n)
716 if (clip_polygon_plane(&n, x, y, &pl_left))
719 dealloc_float(&x, &y, 0);
721 if (clip_polygon_plane(&n, x, y, &pl_rite))
724 dealloc_float(&x, &y, 1);
726 if (clip_polygon_plane(&n, x, y, &pl_bot))
729 dealloc_float(&x, &y, 1);
731 if (clip_polygon_plane(&n, x, y, &pl_top))
734 dealloc_float(&x, &y, 1);
737 n = do_filter(xi, yi, n);
748 do_ll_wrap(x, y, n, polygon_clip);
750 polygon_clip(x, y, n);
753 static void box_clip(
double x1,
double y1,
double x2,
double y2)
771 static void box_clip_ll(
double x1,
double y1,
double x2,
double y2)
773 double ux0 = clip.
left;
774 double ux1 = clip.
rite;
777 x2 = x1 + coerce(x2 - x1);
779 lo = -shift_count(ux1 - x1);
780 hi = shift_count(x2 - ux0);
782 for (i = lo; i <= hi; i++)
783 box_clip(x1 + i * 360, y1, x2 + i * 360, y2);
792 box_clip_ll(x1, y1, x2, y2);
794 box_clip(x1, y1, x2, y2);
816 n = do_filter(xi, yi, n);
823 n = do_filter(xi, yi, n);
830 n = do_filter(xi, yi, n);
834 void D_box(
double x1,
double y1,
double x2,
double y2)
836 double l =
min(x1, x2);
837 double r =
max(x1, x2);
838 double b =
min(y1, y2);
839 double t =
max(y1, y2);
void D_set_clip(double t, double b, double l, double r)
set clipping window
void R_polygon_abs(const int *xarray, const int *yarray, int number)
draw a closed polygon
void G_free(void *buf)
Free allocated memory.
void R_box_abs(int x1, int y1, int x2, int y2)
fill a box
void D_polydots(const double *x, const double *y, int n)
void R_line_width(int width)
change the width of line
void D_polyline_clip(const double *x, const double *y, int n)
void D_box_clip(double x1, double y1, double x2, double y2)
double D_get_u_north(void)
void D_polygon(const double *x, const double *y, int n)
void D_line_width(double d)
void R_polyline_abs(const int *xarray, const int *yarray, int number)
draw an open polygon
double D_get_u_east(void)
void R_cont_abs(int x, int y)
draw line
double D_u_to_d_col(double U_col)
earth to screen (east)
void R_move_abs(int x, int y)
move current location
void D_polyline(const double *x, const double *y, int n)
void D_move(double x, double y)
double D_get_u_south(void)
void D_polygon_cull(const double *x, const double *y, int n)
int D_cont_clip(double x, double y)
void R_polydots_abs(const int *xarray, const int *yarray, int number)
draw a series of dots
void D_box(double x1, double y1, double x2, double y2)
void D_move_clip(double x, double y)
move to pixel
void D_polydots_clip(const double *x, const double *y, int n)
void D_polygon_clip(const double *x, const double *y, int n)
void D_polyline_cull(const double *x, const double *y, int n)
void D_cont(double x, double y)
double D_u_to_d_row(double U_row)
earth to screen (north)
double D_get_u_west(void)
void D_clip_to_map(void)
set clipping window to map window