return dp < 0.0 ? -1 : 1;
}
-/**
-* Bitmask elements for edge_intersects() return value.
-*/
-#define PIR_NO_INTERACT 0x00
-#define PIR_INTERSECTS 0x01
-#define PIR_COLINEAR 0x02
-#define PIR_A_TOUCH_LEFT 0x04
-#define PIR_A_TOUCH_RIGHT 0x08
-#define PIR_B_TOUCH_LEFT 0x10
-#define PIR_B_TOUCH_RIGHT 0x20
-
/**
* Returns non-zero if edges A and B interact. The type of interaction is given in the
* return value with the bitmask elements defined above.
*/
-static int
+int
edge_intersects(const POINT3D *A1, const POINT3D *A2, const POINT3D *B1, const POINT3D *B2)
{
POINT3D A3, B3; /* Extra vector to build more cross-product-friendly angles */
*/
#define signum(a) ((a) < 0 ? -1 : ((a) > 0 ? 1 : (a)))
+
+/**
+* Bitmask elements for edge_intersects() return value.
+*/
+#define PIR_NO_INTERACT 0x00
+#define PIR_INTERSECTS 0x01
+#define PIR_COLINEAR 0x02
+#define PIR_A_TOUCH_LEFT 0x04
+#define PIR_A_TOUCH_RIGHT 0x08
+#define PIR_B_TOUCH_LEFT 0x10
+#define PIR_B_TOUCH_RIGHT 0x20
+
+
/*
* Geodetic calculations
*/
int edge_calculate_gbox(const GEOGRAPHIC_EDGE *e, GBOX *gbox);
int edge_calculate_gbox_slow(const GEOGRAPHIC_EDGE *e, GBOX *gbox);
int edge_intersection(const GEOGRAPHIC_EDGE *e1, const GEOGRAPHIC_EDGE *e2, GEOGRAPHIC_POINT *g);
+int edge_intersects(const POINT3D *A1, const POINT3D *A2, const POINT3D *B1, const POINT3D *B2);
double edge_distance_to_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POINT *gp, GEOGRAPHIC_POINT *closest);
double edge_distance_to_edge(const GEOGRAPHIC_EDGE *e1, const GEOGRAPHIC_EDGE *e2, GEOGRAPHIC_POINT *closest1, GEOGRAPHIC_POINT *closest2);
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g);
*/
int circ_tree_contains_point(const CIRC_NODE* node, const POINT2D* pt, const POINT2D* pt_outside, int* on_boundary)
{
- GEOGRAPHIC_POINT closest, crossing;
+ GEOGRAPHIC_POINT closest;
GEOGRAPHIC_EDGE stab_edge, edge;
+ POINT3D S1, S2, E1, E2;
double d;
int i, c;
/* Construct a stabline edge from our "inside" to our known outside point */
geographic_point_init(pt->x, pt->y, &(stab_edge.start));
geographic_point_init(pt_outside->x, pt_outside->y, &(stab_edge.end));
+ geog2cart(&(stab_edge.start), &S1);
+ geog2cart(&(stab_edge.end), &S2);
LWDEBUG(3, "entered");
/* Return the crossing number of this leaf */
if ( circ_node_is_leaf(node) )
{
+ int inter;
LWDEBUGF(3, "leaf node calculation (edge %d)", node->edge_num);
geographic_point_init(node->p1->x, node->p1->y, &(edge.start));
geographic_point_init(node->p2->x, node->p2->y, &(edge.end));
- if ( edge_intersection(&stab_edge, &edge, &crossing) )
+ geog2cart(&(edge.start), &E1);
+ geog2cart(&(edge.end), &E2);
+
+ inter = edge_intersects(&S1, &S2, &E1, &E2);
+
+ if ( inter & PIR_INTERSECTS )
{
LWDEBUG(3," got stab line edge_intersection with this edge!");
/* To avoid double counting crossings-at-a-vertex, */
/* always ignore crossings at "lower" ends of edges*/
- if ( (FP_EQUALS(crossing.lon, edge.start.lon) && FP_EQUALS(crossing.lat, edge.start.lat) && (edge.start.lat <= edge.end.lat)) ||
- (FP_EQUALS(crossing.lon, edge.end.lon) && FP_EQUALS(crossing.lat, edge.end.lat) && (edge.end.lat <= edge.start.lat)) )
+
+ if ( inter & PIR_B_TOUCH_LEFT || inter & PIR_COLINEAR )
{
- LWDEBUG(3," rejecting stab line intersection on 'lower' end point vertex");
+ LWDEBUG(3," rejecting stab line grazing by left-side edge");
return 0;
}
else