GRASS Programmer's Manual  6.4.4(2014)-r
stroke.c
Go to the documentation of this file.
1 
2 /****************************************************************************
3 *
4 * MODULE: Symbol library
5 *
6 * AUTHOR(S): Radim Blazek
7 *
8 * PURPOSE: Stroke symbol
9 *
10 * COPYRIGHT: (C) 2001 by the GRASS Development Team
11 *
12 * This program is free software under the GNU General Public
13 * License (>=v2). Read the file COPYING that comes with GRASS
14 * for details.
15 *
16 *****************************************************************************/
17 #include <stdlib.h>
18 #include <math.h>
19 #include <grass/gis.h>
20 #include <grass/symbol.h>
21 
22 #define PI M_PI
23 
24 void add_coor(SYMBCHAIN * chain, int x, int y)
25 {
26  G_debug(5, " add_coor %d, %d", x, y);
27  if (chain->scount == chain->salloc) {
28  chain->salloc += 10;
29  chain->sx = (int *)G_realloc(chain->sx, chain->salloc * sizeof(int));
30  chain->sy = (int *)G_realloc(chain->sy, chain->salloc * sizeof(int));
31  }
32  chain->sx[chain->scount] = x;
33  chain->sy[chain->scount] = y;
34  chain->scount++;
35 }
36 
37 /* draw chain
38  * s - scale
39  * ch - chain number
40  * rotation - degrees CCW from East
41  */
42 int stroke_chain(SYMBPART * part, int ch, double s, double rotation)
43 {
44  int k, l, first;
45  SYMBEL *elem;
46  SYMBCHAIN *chain;
47  double r;
48  double a1, a2, da;
49  int x, y, x0, y0;
50 
51  G_debug(5, " stroke_chain(): ch = %d", ch);
52  chain = part->chain[ch];
53 
54  G_debug(5, " element count = %d", chain->count);
55  first = 1;
56  for (k = 0; k < chain->count; k++) {
57  elem = chain->elem[k];
58  switch (elem->type) {
59  case S_LINE:
60  G_debug(5, " LINE count = %d", elem->coor.line.count);
61  for (l = 0; l < elem->coor.line.count; l++) {
62  x = s * elem->coor.line.x[l];
63  y = s * elem->coor.line.y[l];
64 
65  if (rotation != 0.0)
66  G_rotate_around_point_int(0, 0, &x, &y, rotation);
67 
68  add_coor(chain, x, y);
69  if (first) {
70  x0 = x;
71  y0 = y;
72  first = 0;
73  }
74  }
75  break;
76  case S_ARC:
77  if (s >= 50)
78  da = 1 * PI / 180; /* later calc from size and tolerance */
79  else
80  da = 10 * PI / 180;
81 
82  r = elem->coor.arc.r;
83  G_debug(5, " ARC da = %f r = %f", da, r);
84 
85  /* convert to positive angles */
86  a1 = PI * elem->coor.arc.a1 / 180;
87  if (a1 < 0)
88  a1 += 2 * PI;
89  a2 = PI * elem->coor.arc.a2 / 180;
90  if (a2 < 0)
91  a2 += 2 * PI;
92 
93  if (elem->coor.arc.clock) { /* clockwise */
94  while (1) {
95  x = s * elem->coor.arc.x + s * r * cos(a1);
96  y = s * elem->coor.arc.y + s * r * sin(a1);
97 
98  if (rotation != 0.0)
99  G_rotate_around_point_int(0, 0, &x, &y, rotation);
100 
101  add_coor(chain, x, y);
102  if (first) {
103  x0 = x;
104  y0 = y;
105  first = 0;
106  }
107  if (a1 == a2)
108  break;
109  a1 -= da;
110  if (a1 < a2)
111  a1 = a2;
112  }
113 
114  }
115  else {
116  while (1) {
117  x = s * elem->coor.arc.x + s * r * cos(a1);
118  y = s * elem->coor.arc.y + s * r * sin(a1);
119 
120  if (rotation != 0.0)
121  G_rotate_around_point_int(0, 0, &x, &y, rotation);
122 
123  add_coor(chain, x, y);
124  if (first) {
125  x0 = x;
126  y0 = y;
127  first = 0;
128  }
129  if (a1 == a2)
130  break;
131  a1 += da;
132  if (a1 > a2)
133  a1 = a2;
134  }
135  }
136  break;
137  }
138  }
139  if (part->type == S_POLYGON) {
140  add_coor(chain, x0, y0); /* Close ring */
141  }
142 
143  return 0;
144 }
145 
146 /*
147  * Stroke symbol to form used for Xdriver.
148  *
149  * tolerance currently not supported
150  */
151 void S_stroke(SYMBOL *Symb, int size, double rotation, int tolerance)
152 {
153  int i, j;
154  double s;
155  SYMBPART *part;
156 
157  G_debug(3, "S_stroke(): size = %d rotation = %f tolerance = %d", size,
158  rotation, tolerance);
159 
160  /* TODO: support for tolerance */
161 
162  s = size * Symb->scale;
163 
164  for (i = 0; i < Symb->count; i++) {
165  G_debug(4, " part %d", i);
166  part = Symb->part[i];
167  switch (part->type) {
168  case S_POLYGON:
169  for (j = 0; j < part->count; j++) { /* RINGS */
170  stroke_chain(part, j, s, rotation);
171  }
172  break;
173  case S_STRING: /* string has 1 chain */
174  stroke_chain(part, 0, s, rotation);
175  break;
176  }
177  }
178 }
void S_stroke(SYMBOL *Symb, int size, double rotation, int tolerance)
Definition: stroke.c:151
float r
Definition: named_colr.c:8
int y
Definition: plot.c:34
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
int first
Definition: form/open.c:25
#define PI
Definition: stroke.c:22
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
void add_coor(SYMBCHAIN *chain, int x, int y)
Definition: stroke.c:24
void G_rotate_around_point_int(int X0, int Y0, int *X1, int *Y1, double angle)
Rotate point (int version)
Definition: rotate.c:62
int stroke_chain(SYMBPART *part, int ch, double s, double rotation)
Definition: stroke.c:42