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