26 (((A) > 0 && (B) < 0) || ((A) < 0 && (B) > 0) ? (((A) + (B)) / 2.) \
27 : ((A) + ((B) - (A)) / 2.))
35static int comp_double(
const void *,
const void *);
36static int V__within(
double,
double,
double);
41static void destroy_links(
struct link_head *,
struct Slink *);
42static int Vect__divide_and_conquer(
struct Slink *,
const struct line_pnts *,
65 static int first_time = 1;
69 G_debug(3,
"Vect_get_point_in_area()");
88 for (i = 0; i < n_isles; i++) {
101static int comp_double(
const void *i,
const void *
j)
103 if (*(
const double *)i < *(
const double *)
j)
106 return (*(
const double *)i > *(
const double *)
j);
109static int V__within(
double a,
double x,
double b)
112 return (
x >= a &&
x <
b);
114 return (
x >
b &&
x <= a);
136 double a,
b, c, d,
x;
139 for (i = 1; i < Points->
n_points; i++) {
140 a = Points->
y[i - 1];
143 c = Points->
x[i - 1];
148 if (
b < a || (
b == a && d < c)) {
158 if (V__within(a,
y,
b)) {
162 p = (
y - a) / (
b - a);
191 double a,
b, c, d,
y;
194 for (i = 1; i < Points->
n_points; i++) {
195 a = Points->
x[i - 1];
198 c = Points->
y[i - 1];
203 if (
b < a || (
b == a && d < c)) {
213 if (V__within(a,
x,
b)) {
217 p = (
x - a) / (
b - a);
244 static int first_time = 1;
259 G_debug(3,
"Vect_get_point_in_poly(): divide and conquer");
263 for (i = 0; i < Points->
n_points; i++) {
293 G_warning(
"Vect_get_point_in_poly(): %s",
294 _(
"Unable to find point in polygon"));
298 G_debug(3,
"Found point in %d iterations", 10 -
ret);
325static int Vect__divide_and_conquer(
struct Slink *
Head,
330 struct Slink *A, *B, *C;
341 C->x = (A->x + B->x) / 2.;
365 struct Slink *p, *tmp;
404 for (i = 1; i < points->
n_points; i++) {
453 x = (box.
W + box.
E) / 2.;
454 y = (box.
S + box.
N) / 2.;
463 for (i = 1; i < Points->
n_points; i++) {
464 w = (
x -
xp[i - 1]) * (
yp[i] - y) - (
x -
xp[i]) * (
yp[i - 1] - y);
475 w = (
x -
xp[i - 1]) * (
yp[i] - y) - (
x -
xp[i]) * (
yp[i - 1] - y);
552 static int first_time = 1;
564 G_debug(3,
"Vect_get_point_in_poly_isl(): n_isles = %d", n_isles);
576 "Vect_get_point_in_poly_isl(): outer ring with less than 4 points");
594 for (i = 0; i < n_isles; i++) {
616 for (i = 0; i < n_isles; i++) {
629 G_debug(3,
"Vect_get_point_in_poly_isl(): the hard way");
643 for (i = 0; i < Points->
n_points; i++) {
658 for (i = 0; i < Points->
n_points; i++) {
662 if ((Points->
y[i] >=
cent_y) &&
669 if ((Points->
x[i] >=
cent_x) &&
673 for (i = 0; i < n_isles; i++) {
693 G_debug(3,
"Vect_get_point_in_poly_isl(): lo_y == hi_y");
705 for (i = 0; i < n_isles; i++) {
712 G_debug(3,
"Vect_get_point_in_poly_isl(): no x intersections");
725 for (i = 0; i <
Intersects->n_points; i += 2) {
753 G_debug(3,
"Vect_get_point_in_poly_isl(): trying x intersect");
756 G_debug(3,
"Vect_get_point_in_poly_isl(): lo_x == hi_x");
768 for (i = 0; i < n_isles; i++) {
775 G_debug(3,
"Vect_get_point_in_poly_isl(): no y intersections");
787 for (i = 0; i <
Intersects->n_points; i += 2) {
809 G_warning(
"Vect_get_point_in_poly_isl(): collapsed area");
824 G_warning(
"Vect_get_point_in_poly_isl(), the hard way: centroid is on "
825 "outer ring, max dist is %g",
832 for (i = 0; i < n_isles; i++) {
835 G_warning(
"Vect_get_point_in_poly_isl(), the hard way: "
836 "centroid is in isle, max dist is %g",
853static int segments_x_ray(
double X,
double Y,
const struct line_pnts *Points)
855 double x1, x2, y1, y2;
860 G_debug(3,
"segments_x_ray(): x = %f y = %f n_points = %d",
X,
Y,
868 for (n = 1; n < Points->
n_points; n++) {
869 x1 = Points->
x[n - 1];
870 y1 = Points->
y[n - 1];
887 if (y1 >
Y && y2 >
Y)
891 if (y1 <
Y && y2 <
Y)
895 if (x1 <
X && x2 <
X)
899 if ((x1 ==
X && y1 ==
Y) || (x2 ==
X && y2 ==
Y))
903 if (x1 == x2 && x1 ==
X) {
909 if (y1 == y2 && y1 ==
Y) {
921 if ((y1 ==
Y && y2 >
Y) || (y2 ==
Y && y1 >
Y))
927 if (y1 ==
Y && y2 <
Y) {
932 if (y2 ==
Y && y1 <
Y) {
940 if (x1 >=
X && x2 >=
X) {
961 G_warning(
"segments_x_ray() %s: X = %f Y = %f x1 = %f y1 = %f x2 = %f "
963 _(
"conditions failed"),
X,
Y, x1, y1, x2, y2);
983 G_debug(3,
"Vect_point_in_poly(): x = %f y = %f n_points = %d",
X,
Y,
1012 static int first = 1;
1017 G_debug(3,
"Vect_point_in_area_outer_ring(): x = %f y = %f area = %d",
X,
Y,
1050 static int first = 1;
1055 G_debug(3,
"Vect_point_in_island(): x = %f y = %f isle = %d",
X,
Y,
isle);
int Vect_find_poly_centroid_cog(const struct line_pnts *Points, const struct line_pnts **IPoints, int n_isles, double *cent_x, double *cent_y)
Get centroid of polygon.
int Vect_get_point_in_poly_isl(const struct line_pnts *Points, const struct line_pnts **IPoints, int n_isles, double *att_x, double *att_y)
Get point inside polygon but outside the islands specifiled in IPoints.
int Vect_point_in_poly(double X, double Y, const struct line_pnts *Points)
Determines if a point (X,Y) is inside a polygon.
int Vect_get_point_in_poly(const struct line_pnts *Points, double *X, double *Y)
Get point inside polygon.
int Vect_find_poly_centroid(const struct line_pnts *points, double *cent_x, double *cent_y)
Get centroid of polygon.
int Vect__intersect_x_line_with_poly(const struct line_pnts *, double, struct line_pnts *)
int Vect__intersect_y_line_with_poly(const struct line_pnts *, double, struct line_pnts *)
int Vect_point_in_island(double X, double Y, struct Map_info *Map, int isle, struct bound_box *box)
Determines if a point (X,Y) is inside an island.
int Vect_point_in_area_outer_ring(double X, double Y, struct Map_info *Map, int area, struct bound_box *box)
Determines if a point (X,Y) is inside an area outer ring. Islands are not considered.
int Vect_get_point_in_area(struct Map_info *Map, int area, double *X, double *Y)
Get point inside area and outside all islands.
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
VOID_T * link_new(struct link_head *)
void link_dispose(struct link_head *, VOID_T *)
void link_exit_on_error(int)
struct link_head * link_init(int)
void Vect_line_box(const struct line_pnts *, struct bound_box *)
Get bounding box of line.
int Vect_get_isle_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points for given isle.
int Vect_get_area_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points (outer ring) of given area.
int Vect_get_area_isle(struct Map_info *, int, int)
Returns isle id for area.
int Vect_get_area_num_isles(struct Map_info *, int)
Returns number of isles for given area.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
double dig_x_intersect(double, double, double, double, double)
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.