grass  7.8.6
About: GRASS (Geographic Resources Analysis Support System) is a raster- and vector-based GIS, image processing system, graphics production system and spatial modeling system.
  Fossies Dox: grass-7.8.6.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

draw2.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 "driver.h"
9#include "path.h"
10#include "clip.h"
11
12struct vector
13{
14 double x, y;
15};
16
17/******************************************************************************/
18
19static struct path path;
20
21static int clip_mode = M_NONE;
22static double epsilon = 0.0;
23static struct path ll_path, clip_path, raw_path, eps_path;
24
25static struct vector cur;
26
27static struct rectangle clip;
28
29static int window_set;
30
31#define min(x,y) ((x) < (y) ? (x) : (y))
32#define max(x,y) ((x) > (y) ? (x) : (y))
33
34/******************************************************************************/
35
36static int shift_count(double dx)
37{
38 return (int)floor(dx / 360);
39}
40
41static double shift_angle(double dx)
42{
43 return shift_count(dx) * 360;
44}
45
46static double coerce(double x)
47{
48 x += 180;
49 x -= shift_angle(x);
50 x -= 180;
51 return x;
52}
53
54static int euclidify(struct path *p, int no_pole)
55{
56 double ux0 = clip.left;
57 double ux1 = clip.rite;
58 double x0, x1;
59 int lo, hi, count;
60 int i;
61
62 x0 = x1 = p->vertices[0].x;
63
64 for (i = 1; i < p->count; i++) {
65 if (fabs(p->vertices[i].y) < 89.9)
66 p->vertices[i].x = p->vertices[i-1].x + coerce(p->vertices[i].x - p->vertices[i-1].x);
67
68 x0 = min(x0, p->vertices[i].x);
69 x1 = max(x1, p->vertices[i].x);
70 }
71
72 if (no_pole && fabs(p->vertices[p->count-1].x - p->vertices[0].x) > 180)
73 return 0;
74
75 lo = -shift_count(ux1 - x0);
76 hi = shift_count(x1 - ux0);
77 count = hi - lo + 1;
78
79 for (i = 0; i < p->count; i++)
80 p->vertices[i].x -= lo * 360;
81
82 return count;
83}
84
85static void ll_wrap_path(struct path *dst, const struct path *src, int no_pole)
86{
87 int count, i, j;
88
90
91 count = euclidify(dst, no_pole);
92
93 for (i = 0; i < count; i++) {
94 for (j = 0; j < src->count; j++) {
95 struct vertex *v = &dst->vertices[j];
96 path_append(dst, v->x - i * 360, v->y, v->mode);
97 }
98 }
99}
100
101static void conv_path(struct path *dst, const struct path *src)
102{
103 int i;
104
105 path_copy(dst, src);
106
107 for (i = 0; i < dst->count; i++) {
108 struct vertex *v = &dst->vertices[i];
109 v->x = D_u_to_d_col(v->x);
110 v->y = D_u_to_d_row(v->y);
111 }
112}
113
114static void reduce_path(struct path *dst, const struct path *src, double eps)
115{
116 struct vertex *v = &src->vertices[0];
117 int i;
118
120 path_append(dst, v->x, v->y, v->mode);
121
122 for (i = 1; i < src->count - 1; i++) {
123 struct vertex *v0 = &dst->vertices[dst->count-1];
124 struct vertex *v1 = &src->vertices[i];
125 struct vertex *v2 = &src->vertices[i+1];
126
127 if (fabs(v1->x - v0->x) < eps && fabs(v1->y - v0->y) < eps &&
128 fabs(v1->x - v2->x) < eps && fabs(v1->y - v2->y) < eps &&
129 v0->mode != P_MOVE && v1->mode != P_MOVE && !v2->mode != P_MOVE)
130 continue;
131
132 path_append(dst, v1->x, v1->y, v1->mode);
133 }
134 v = &src->vertices[src->count - 1];
135 path_append(dst, v->x, v->y, v->mode);
136}
137
138/******************************************************************************/
139
140/*!
141 * \brief set clipping window
142 *
143 * Sets the clipping window to the pixel window that corresponds
144 * to the current database region. This is the default.
145 *
146 * \param t top
147 * \param b bottom
148 * \param l left
149 * \param r right
150 */
151
152void D_set_clip(double t, double b, double l, double r)
153{
154 clip.left = min(l, r);
155 clip.rite = max(l, r);
156 clip.bot = min(b, t);
157 clip.top = max(b, t);
158
159 window_set = 1;
160}
161
162/*!
163 * \brief set clipping window to map window
164 *
165 * Sets the clipping window to the pixel window that corresponds to the
166 * current database region. This is the default.
167 *
168 * \param ~
169 */
170
172{
173 double t, b, l, r;
174
175 D_get_src(&t, &b, &l, &r);
176 D_set_clip(t, b, l, r);
177}
178
180{
181 clip_mode = mode;
182}
183
184void D_set_reduction(double e)
185{
186 epsilon = e;
187}
188
189void D_line_width(double d)
190{
191 COM_Line_width(d > 0 ? d : 0);
192}
193
194void D_get_text_box(const char *text, double *t, double *b, double *l, double *r)
195{
196 double T, B, L, R;
197
198 COM_Get_text_box(text, &T, &B, &L, &R);
199
200 *t = D_d_to_u_row(T);
201 *b = D_d_to_u_row(B);
202 *l = D_d_to_u_col(L);
203 *r = D_d_to_u_col(R);
204
205 if (*t < *b) {
206 double tmp = *t; *t = *b; *b = tmp;
207 }
208
209 if (*r < *l) {
210 double tmp = *r; *r = *l; *l = tmp;
211 }
212}
213
214/******************************************************************************/
215
216/* D_pos_abs(easting, northing): move to an absolute position
217 on the display using map coordinates */
218void D_pos_abs(double x, double y)
219{
220 cur.x = x;
221 cur.y = y;
222
223 x = D_u_to_d_col(x);
224 y = D_u_to_d_row(y);
225
226 COM_Pos_abs(x, y);
227}
228
229void D_pos_rel(double x, double y)
230{
231 D_pos_abs(cur.x + x, cur.y + y);
232}
233
234/******************************************************************************/
235
236static void do_path(int no_pole)
237{
238 struct path *p = &path;
239 struct clip planes;
240 int i;
241
242 if (!window_set)
244
245 if (D_is_lat_lon()) {
246 ll_wrap_path(&ll_path, p, no_pole);
247 p = &ll_path;
248 }
249
250 switch (clip_mode) {
251 case M_NONE:
252 break;
253 case M_CULL:
254 D__set_clip_planes(&planes, &clip);
255 D__cull_path(&clip_path, p, &planes);
256 p = &clip_path;
257 break;
258 case M_CLIP:
259 D__set_clip_planes(&planes, &clip);
260 D__clip_path(&clip_path, p, &planes);
261 p = &clip_path;
262 break;
263 }
264
265 conv_path(&raw_path, p);
266 p = &raw_path;
267
268 if (epsilon > 0) {
270 p = &eps_path;
271 }
272
273 COM_Begin();
274 for (i = 0; i < p->count; i++) {
275 struct vertex *v = &p->vertices[i];
276 switch (v->mode)
277 {
278 case P_MOVE:
279 COM_Move(v->x, v->y);
280 break;
281 case P_CONT:
282 COM_Cont(v->x, v->y);
283 break;
284 case P_CLOSE:
285 COM_Close();
286 break;
287 }
288 }
289}
290
291void D_begin(void)
292{
294}
295
296void D_end(void)
297{
298}
299
300/* D_move_abs(x,y): move to an absolute position on the display using
301 display pixel coordinates */
302void D_move_abs(double x, double y)
303{
304 path_move(&path, x, y);
305
306 cur.x = x;
307 cur.y = y;
308}
309
310void D_cont_abs(double x, double y)
311{
312 path_cont(&path, x, y);
313
314 cur.x = x;
315 cur.y = y;
316}
317
318void D_close(void)
319{
321}
322
323void D_stroke(void)
324{
325 do_path(0);
326 COM_Stroke();
327}
328
329void D_fill(void)
330{
331 do_path(1);
332 COM_Fill();
333}
334
335void D_dots(void)
336{
337 struct path *p = &path;
338 int i;
339
340 if (!window_set)
342
343 for (i = 0; i < p->count; i++) {
344 struct vertex *v = &p->vertices[i];
345 double x = v->x;
346 double y = v->y;
347
348 if (D_is_lat_lon())
349 x = coerce(x);
350
351 if (clip_mode != M_NONE) {
352 if (x < clip.left || x > clip.rite)
353 continue;
354 if (y < clip.bot || y > clip.top)
355 continue;
356 }
357
358 x = D_u_to_d_col(x);
359 y = D_u_to_d_row(y);
360
361 COM_Point(x, y);
362 }
363}
364
365/******************************************************************************/
366
367static void poly_abs(const double *x, const double *y, int n)
368{
369 int i;
370
371 if (n < 2)
372 return;
373
374 D_begin();
375 D_move_abs(x[0], y[0]);
376 for (i = 1; i < n; i++)
377 D_cont_abs(x[i], y[i]);
378}
379
380void D_polyline_abs(const double *x, const double *y, int n)
381{
382 poly_abs(x, y, n);
383 D_stroke();
384}
385
386void D_polygon_abs(const double *x, const double *y, int n)
387{
388 poly_abs(x, y, n);
389 D_close();
390 D_fill();
391}
392
393void D_polydots_abs(const double *x, const double *y, int n)
394{
395 poly_abs(x, y, n);
396 D_dots();
397}
398
399void D_line_abs(double x1, double y1, double x2, double y2)
400{
401 D_begin();
402 D_move_abs(x1, y1);
403 D_cont_abs(x2, y2);
404 D_end();
405 D_stroke();
406}
407
408void D_box_abs(double x1, double y1, double x2, double y2)
409{
410 struct vector save = cur;
411
412 D_begin();
413 D_move_abs(x1, y1);
414 D_cont_abs(x2, y1);
415 D_cont_abs(x2, y2);
416 D_cont_abs(x1, y2);
417 D_close();
418 D_end();
419 D_fill();
420
421 cur = save;
422}
423
424/******************************************************************************/
425
426static void poly_rel(const double *x, const double *y, int n)
427{
428 int i;
429
430 if (n < 2)
431 return;
432
433 D_begin();
434 D_move_rel(x[0], y[0]);
435 for (i = 1; i < n; i++)
436 D_cont_rel(x[i], y[i]);
437}
438
439void D_move_rel(double x, double y)
440{
441 D_move_abs(cur.x + x, cur.y + y);
442}
443
444void D_cont_rel(double x, double y)
445{
446 D_cont_abs(cur.x + x, cur.y + y);
447}
448
449void D_polydots_rel(const double *x, const double *y, int n)
450{
451 poly_rel(x, y, n);
452 D_dots();
453}
454
455void D_polyline_rel(const double *x, const double *y, int n)
456{
457 poly_rel(x, y, n);
458 D_stroke();
459}
460
461void D_polygon_rel(const double *x, const double *y, int n)
462{
463 poly_rel(x, y, n);
464 D_close();
465 D_fill();
466}
467
468void D_line_rel(double x1, double y1, double x2, double y2)
469{
470 cur.x += x1;
471 cur.y += y1;
472
473 x1 = cur.x;
474 y1 = cur.y;
475
476 cur.x += x2;
477 cur.y += y2;
478
479 x2 = cur.x;
480 y2 = cur.y;
481
482 D_line_abs(x1, y1, x2, y2);
483}
484
485void D_box_rel(double x2, double y2)
486{
487 D_box_abs(cur.x, cur.y, cur.x + x2, cur.y + y2);
488}
489
490/******************************************************************************/
491
void D__cull_path(struct path *dst, const struct path *src, const struct clip *clip)
Definition: clip.c:129
void D__clip_path(struct path *dst, const struct path *src, const struct clip *clip)
Definition: clip.c:145
void D__set_clip_planes(struct clip *clip, const struct rectangle *rect)
Definition: clip.c:110
void D_get_src(double *t, double *b, double *l, double *r)
returns frame bounds in source coordinate system
Definition: cnversions.c:226
double D_d_to_u_col(double D_col)
screen to earth (x)
Definition: cnversions.c:364
double D_u_to_d_col(double U_col)
earth to screen (east)
Definition: cnversions.c:462
int D_is_lat_lon(void)
Definition: cnversions.c:165
double D_u_to_d_row(double U_row)
earth to screen (north)
Definition: cnversions.c:446
double D_d_to_u_row(double D_row)
screen to earth (y)
Definition: cnversions.c:348
static int src[2][2]
Definition: raster.c:25
static double dst[2][2]
Definition: raster.c:26
clip_mode
Definition: display.h:21
@ M_CULL
Definition: display.h:23
@ M_CLIP
Definition: display.h:24
@ M_NONE
Definition: display.h:22
static double coerce(double x)
Definition: draw2.c:46
static void poly_abs(const double *x, const double *y, int n)
Definition: draw2.c:367
void D_polydots_abs(const double *x, const double *y, int n)
Definition: draw2.c:393
void D_pos_abs(double x, double y)
Definition: draw2.c:218
void D_stroke(void)
Definition: draw2.c:323
void D_end(void)
Definition: draw2.c:296
void D_set_clip(double t, double b, double l, double r)
set clipping window
Definition: draw2.c:152
static void do_path(int no_pole)
Definition: draw2.c:236
static double epsilon
Definition: draw2.c:22
void D_move_rel(double x, double y)
Definition: draw2.c:439
void D_line_abs(double x1, double y1, double x2, double y2)
Definition: draw2.c:399
void D_get_text_box(const char *text, double *t, double *b, double *l, double *r)
Definition: draw2.c:194
void D_box_rel(double x2, double y2)
Definition: draw2.c:485
static struct vector cur
Definition: draw2.c:25
static void reduce_path(struct path *dst, const struct path *src, double eps)
Definition: draw2.c:114
void D_fill(void)
Definition: draw2.c:329
void D_pos_rel(double x, double y)
Definition: draw2.c:229
static double shift_angle(double dx)
Definition: draw2.c:41
static int window_set
Definition: draw2.c:29
static struct path path
Definition: draw2.c:19
void D_cont_rel(double x, double y)
Definition: draw2.c:444
void D_line_width(double d)
Definition: draw2.c:189
void D_polydots_rel(const double *x, const double *y, int n)
Definition: draw2.c:449
static int euclidify(struct path *p, int no_pole)
Definition: draw2.c:54
void D_cont_abs(double x, double y)
Definition: draw2.c:310
void D_line_rel(double x1, double y1, double x2, double y2)
Definition: draw2.c:468
static void conv_path(struct path *dst, const struct path *src)
Definition: draw2.c:101
void D_set_reduction(double e)
Definition: draw2.c:184
void D_clip_to_map(void)
set clipping window to map window
Definition: draw2.c:171
static struct path ll_path clip_path raw_path eps_path
Definition: draw2.c:23
#define min(x, y)
Definition: draw2.c:31
void D_polyline_rel(const double *x, const double *y, int n)
Definition: draw2.c:455
#define max(x, y)
Definition: draw2.c:32
static void ll_wrap_path(struct path *dst, const struct path *src, int no_pole)
Definition: draw2.c:85
void D_dots(void)
Definition: draw2.c:335
void D_polyline_abs(const double *x, const double *y, int n)
Definition: draw2.c:380
void D_close(void)
Definition: draw2.c:318
void D_move_abs(double x, double y)
Definition: draw2.c:302
static void poly_rel(const double *x, const double *y, int n)
Definition: draw2.c:426
void D_begin(void)
Definition: draw2.c:291
void D_box_abs(double x1, double y1, double x2, double y2)
Definition: draw2.c:408
void D_set_clip_mode(int mode)
Definition: draw2.c:179
void D_polygon_rel(const double *x, const double *y, int n)
Definition: draw2.c:461
static int shift_count(double dx)
Definition: draw2.c:36
void D_polygon_abs(const double *x, const double *y, int n)
Definition: draw2.c:386
void COM_Close(void)
Definition: draw.c:29
void COM_Cont(double x, double y)
Definition: draw.c:23
void COM_Fill(void)
Definition: draw.c:41
void COM_Stroke(void)
Definition: draw.c:35
void COM_Move(double x, double y)
Definition: draw.c:17
void COM_Begin(void)
Definition: draw.c:11
void COM_Point(double x, double y)
Definition: draw.c:47
void path_close(struct path *p)
Definition: path.c:84
void path_copy(struct path *dst, const struct path *src)
Definition: path.c:52
void path_reset(struct path *p)
Definition: path.c:32
void path_begin(struct path *p)
Definition: path.c:67
void path_cont(struct path *p, double x, double y)
Definition: path.c:79
void path_append(struct path *p, double x, double y, int mode)
Definition: path.c:38
void path_move(struct path *p, double x, double y)
Definition: path.c:73
void COM_Pos_abs(double, double)
Definition: move.c:4
void COM_Get_text_box(const char *, double *, double *, double *, double *)
Definition: get_t_box.c:4
void COM_Line_width(double)
Definition: line_width.c:4
static double * tmp
Definition: fpxdr.c:102
int count
static uint16 x0
Definition: lrand48.c:35
static uint16 x1
Definition: lrand48.c:35
static uint16 x2
Definition: lrand48.c:35
@ P_CONT
Definition: path.h:7
@ P_MOVE
Definition: path.h:6
@ P_CLOSE
Definition: path.h:8
double b
Definition: r_raster.c:39
double l
Definition: r_raster.c:39
double t
Definition: r_raster.c:39
double r
Definition: r_raster.c:39
Definition: clip.h:13
struct plane left rite bot top
Definition: clip.h:14
Definition: path.h:16
int count
Definition: path.h:18
struct vertex * vertices
Definition: path.h:17
Definition: clip.h:18
double x
Definition: cnversions.c:29
double y
Definition: cnversions.c:29
Definition: path.h:11
int mode
Definition: path.h:13
double x
Definition: path.h:12
double y
Definition: path.h:12
static float d[4][4]
Definition: trans.c:49
#define x
static double mode(double *value, int argc)
Definition: xmode.c:25