GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
clip.c
Go to the documentation of this file.
1
2 #include <math.h>
3 #include <string.h>
4
5 #include <grass/gis.h>
6 #include <grass/display.h>
7 #include <grass/glocale.h>
8 #include "path.h"
9 #include "clip.h"
10
11 /******************************************************************************/
12
13 static double dist_plane(double x, double y, const struct plane *p)
14 {
15  return x * p->x + y * p->y + p->k;
16 }
17
18 static double interpolate(double a, double b, double ka, double kb)
19 {
20  return (a * kb - b * ka) / (kb - ka);
21 }
22
23 static void clip_path_plane(struct path *dst, const struct path *src,
24  const struct plane *p)
25 {
26  struct vertex *v0 = &src->vertices[src->count - 1];
27  double x0 = v0->x;
28  double y0 = v0->y;
29  double d0 = dist_plane(x0, y0, p);
30  int i;
31
32  path_reset(dst);
33
34  for (i = 0; i < src->count; i++) {
35  struct vertex *v1 = &src->vertices[i];
36  double x1 = v1->x;
37  double y1 = v1->y;
38  double d1 = dist_plane(x1, y1, p);
39  int in0 = d0 <= 0;
40  int in1 = d1 <= 0;
41
42  if (in0 && !in1) {
43  /* leaving */
44  double x = interpolate(x0, x1, d0, d1);
45  double y = interpolate(y0, y1, d0, d1);
46  path_cont(dst, x, y);
47  }
48
49  if (!in0 && in1) {
50  /* entering */
51  double x = interpolate(x0, x1, d0, d1);
52  double y = interpolate(y0, y1, d0, d1);
53  path_move(dst, x, y);
54  }
55
56  if (in1)
57  /* inside */
58  path_cont(dst, x1, y1);
59
60  x0 = x1;
61  y0 = y1;
62  d0 = d1;
63  }
64 }
65
66 /******************************************************************************/
67
68 static void cull_path_plane(struct path *dst, const struct path *src,
69  const struct plane *p)
70 {
71  int last = -1;
72  int prev = src->count - 1;
73  struct vertex *v0 = &src->vertices[prev];
74  double x0 = v0->x;
75  double y0 = v0->y;
76  double d0 = dist_plane(x0, y0, p);
77  int i;
78
79  path_reset(dst);
80
81  for (i = 0; i < src->count; i++) {
82  struct vertex *v1 = &src->vertices[i];
83  double x1 = v1->x;
84  double y1 = v1->y;
85  double d1 = dist_plane(x1, y1, p);
86  int in0 = d0 <= 0;
87  int in1 = d1 <= 0;
88
89  if (!in0 && in1 && last != prev) {
90  /* entering */
91  path_move(dst, x0, y0);
92  last = prev;
93  }
94
95  if (in1 || in0) {
96  /* inside or leaving */
97  path_cont(dst, x1, y1);
98  last = i;
99  }
100
101  x0 = x1;
102  y0 = y1;
103  d0 = d1;
104  prev = i;
105  }
106 }
107
108 /******************************************************************************/
109
110 void D__set_clip_planes(struct clip *clip, const struct rectangle *rect)
111 {
112  clip->left.x = -1;
113  clip->left.y = 0;
114  clip->left.k = rect->left;
115
116  clip->rite.x = 1;
117  clip->rite.y = 0;
118  clip->rite.k = -rect->rite;
119
120  clip->bot.x = 0;
121  clip->bot.y = -1;
122  clip->bot.k = rect->bot;
123
124  clip->top.x = 0;
125  clip->top.y = 1;
126  clip->top.k = -rect->top;
127 }
128
129 void D__cull_path(struct path *dst, const struct path *src, const struct clip *clip)
130 {
131  struct path tmp1, tmp2;
132
133  path_init(&tmp1);
134  path_init(&tmp2);
135
136  cull_path_plane(&tmp1, src, &clip->left);
137  cull_path_plane(&tmp2, &tmp1, &clip->rite);
138  cull_path_plane(&tmp1, &tmp2, &clip->bot);
139  cull_path_plane(dst, &tmp1, &clip->top);
140
141  path_free(&tmp1);
142  path_free(&tmp2);
143 }
144
145 void D__clip_path(struct path *dst, const struct path *src, const struct clip *clip)
146 {
147  struct path tmp1, tmp2;
148
149  path_init(&tmp1);
150  path_init(&tmp2);
151
152  clip_path_plane(&tmp1, src, &clip->left);
153  clip_path_plane(&tmp2, &tmp1, &clip->rite);
154  clip_path_plane(&tmp1, &tmp2, &clip->bot);
155  clip_path_plane(dst, &tmp1, &clip->top);
156
157  path_free(&tmp1);
158  path_free(&tmp2);
159 }
160
161 /******************************************************************************/
162
void D__set_clip_planes(struct clip *clip, const struct rectangle *rect)
Definition: clip.c:110
Definition: path.h:11
double y
Definition: path.h:12
Definition: clip.h:12
void path_cont(struct path *p, double x, double y)
Definition: driver/path.c:79
char * dst
Definition: lz4.h:599
int count
Definition: path.h:18
void path_free(struct path *p)
Definition: driver/path.c:13
#define x
void path_move(struct path *p, double x, double y)
Definition: driver/path.c:73
double y
Definition: clip.h:9
double top
Definition: clip.h:19
void D__cull_path(struct path *dst, const struct path *src, const struct clip *clip)
Definition: clip.c:129
double k
Definition: clip.h:9
struct vertex * vertices
Definition: path.h:17
void path_reset(struct path *p)
Definition: driver/path.c:32
double b
Definition: r_raster.c:39
double rite
Definition: clip.h:19
void D__clip_path(struct path *dst, const struct path *src, const struct clip *clip)
Definition: clip.c:145
struct plane left rite bot top
Definition: clip.h:14
double x
Definition: clip.h:9
Definition: clip.h:17
double bot
Definition: clip.h:19
Definition: path.h:16
Definition: clip.h:7
void path_init(struct path *p)
Definition: driver/path.c:5
double left
Definition: clip.h:19
double x
Definition: path.h:12