GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
driver/Polygon.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <math.h>
3 #include <grass/gis.h>
4 #include "driver.h"
5 #include "driverlib.h"
6 
7 struct point
8 {
9  int x, y;
10 };
11 
12 static int cmp_int(const void *aa, const void *bb)
13 {
14  const int *a = aa;
15  const int *b = bb;
16 
17  return *a - *b;
18 }
19 
20 static void fill(int x0, int x1, int y)
21 {
22  COM_Box_abs(x0, y, x1, y + 1);
23 }
24 
25 static void line(const struct point *p, int n, int y)
26 {
27  static int *xs;
28  static int max_x;
29  int num_x = 0;
30  int i;
31 
32  for (i = 0; i < n; i++) {
33  const struct point *p0 = &p[i];
34  const struct point *p1 = &p[i + 1];
35  const struct point *tmp;
36  double fx, fy;
37  long x;
38 
39  if (p0->y == p1->y)
40  continue;
41 
42  if (p0->y > p1->y)
43  tmp = p0, p0 = p1, p1 = tmp;
44 
45  if (p0->y > y)
46  continue;
47 
48  if (p1->y <= y)
49  continue;
50 
51  fy = y + 0.5;
52  fx = (double)p1->x * (fy - p0->y) + (double)p0->x * (p1->y - fy);
53  fx /= p1->y - p0->y;
54  x = fx < -0x7fffffff ? -0x7fffffff :
55  fx > 0x7fffffff ? 0x7fffffff : (long)floor(fx + 0.5);
56 
57  if (num_x >= max_x) {
58  max_x += 20;
59  xs = G_realloc(xs, max_x * sizeof(int));
60  }
61 
62  xs[num_x++] = x;
63  }
64 
65  qsort(xs, num_x, sizeof(int), cmp_int);
66 
67  for (i = 0; i + 1 < num_x; i += 2)
68  fill(xs[i], xs[i + 1], y);
69 }
70 
71 static void poly(const struct point *p, int n)
72 {
73  int y0, y1;
74  int i, y;
75 
76  if (n < 3)
77  return;
78 
79  y0 = y1 = p[0].y;
80 
81  for (i = 1; i < n; i++) {
82  if (y0 > p[i].y)
83  y0 = p[i].y;
84 
85  if (y1 < p[i].y)
86  y1 = p[i].y;
87  }
88 
89  if (y0 > screen_bottom || y1 < screen_top)
90  return;
91 
92  if (y0 < screen_top)
93  y0 = screen_top;
94 
95  if (y1 > screen_bottom)
96  y1 = screen_bottom;
97 
98  for (y = y0; y < y1; y++)
99  line(p, n, y);
100 }
101 
102 static void fill_polygon(const int *xarray, const int *yarray, int count)
103 {
104  static struct point *points;
105  static int max_points;
106  int i;
107 
108  if (max_points < count + 1) {
109  max_points = count + 1;
110  points = G_realloc(points, sizeof(struct point) * max_points);
111  }
112 
113  for (i = 0; i < count; i++) {
114  points[i].x = xarray[i];
115  points[i].y = yarray[i];
116  }
117 
118  points[count].x = xarray[0];
119  points[count].y = yarray[0];
120 
121  poly(points, count);
122 }
123 
124 void COM_Polygon_abs(const int *xarray, const int *yarray, int number)
125 {
126  if (driver->Polygon_abs) {
127  (*driver->Polygon_abs) (xarray, yarray, number);
128  return;
129  }
130 
131  fill_polygon(xarray, yarray, number);
132 }
133 
134 void COM_Polygon_rel(const int *xarray, const int *yarray, int number)
135 {
136  static int *xa, *ya;
137  static int nalloc;
138  int i;
139 
140  if (driver->Polygon_rel) {
141  (*driver->Polygon_rel) (xarray, yarray, number);
142  return;
143  }
144 
145  if (number > nalloc) {
146  nalloc = number;
147  xa = G_realloc(xa, (size_t) nalloc * sizeof(int));
148  ya = G_realloc(ya, (size_t) nalloc * sizeof(int));
149  }
150 
151  xa[0] = xarray[0] + cur_x;
152  ya[0] = yarray[0] + cur_y;
153 
154  for (i = 1; i < number; i++) {
155  xa[i] = xa[i - 1] + xarray[i];
156  ya[i] = ya[i - 1] + yarray[i];
157  }
158 
159  COM_Polygon_abs(xa, ya, number);
160 }
int cur_y
Definition: driver/init.c:38
float b
Definition: named_colr.c:8
int count
int screen_top
Definition: driver/init.c:35
void COM_Polygon_abs(const int *, const int *, int)
int y
Definition: plot.c:34
void(* Polygon_abs)(const int *, const int *, int)
Definition: driver.h:45
void COM_Box_abs(int x1, int y1, int x2, int y2)
Definition: driver/Box.c:4
void COM_Polygon_rel(const int *, const int *, int)
void(* Polygon_rel)(const int *, const int *, int)
Definition: driver.h:46
int cur_x
Definition: driver/init.c:37
Definition: driver.h:25
int screen_bottom
Definition: driver/init.c:34
int n
Definition: dataquad.c:291