Datum interpt_pp(PG_FUNCTION_ARGS) { PATH *p1 = PG_GETARG_PATH_P(0); PATH *p2 = PG_GETARG_PATH_P(1); int i, j; LSEG seg1, seg2; bool found; /* We've found the intersection */ found = false; /* Haven't found it yet */ for (i = 0; i < p1->npts - 1 && !found; i++) { regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]); for (j = 0; j < p2->npts - 1 && !found; j++) { regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]); if (DatumGetBool(DirectFunctionCall2(lseg_intersect, LsegPGetDatum(&seg1), LsegPGetDatum(&seg2)))) found = true; } } if (!found) PG_RETURN_NULL(); /* * Note: DirectFunctionCall2 will kick out an error if lseg_interpt() * returns NULL, but that should be impossible since we know the two * segments intersect. */ PG_RETURN_DATUM(DirectFunctionCall2(lseg_interpt, LsegPGetDatum(&seg1), LsegPGetDatum(&seg2))); }
Datum regress_path_dist(PG_FUNCTION_ARGS) { PATH *p1 = PG_GETARG_PATH_P(0); PATH *p2 = PG_GETARG_PATH_P(1); bool have_min = false; float8 min = 0.0; /* initialize to keep compiler quiet */ float8 tmp; int i, j; LSEG seg1, seg2; for (i = 0; i < p1->npts - 1; i++) { for (j = 0; j < p2->npts - 1; j++) { regress_lseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]); regress_lseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]); tmp = DatumGetFloat8(DirectFunctionCall2(lseg_distance, LsegPGetDatum(&seg1), LsegPGetDatum(&seg2))); if (!have_min || tmp < min) { min = tmp; have_min = true; } } } if (!have_min) PG_RETURN_NULL(); PG_RETURN_FLOAT8(min); }
Datum regress_dist_ptpath(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); PATH *path = PG_GETARG_PATH_P(1); float8 result = 0.0; /* keep compiler quiet */ float8 tmp; int i; LSEG lseg; switch (path->npts) { case 0: PG_RETURN_NULL(); case 1: result = point_dt(pt, &path->p[0]); break; default: /* * the distance from a point to a path is the smallest distance * from the point to any of its constituent segments. */ Assert(path->npts > 1); for (i = 0; i < path->npts - 1; ++i) { regress_lseg_construct(&lseg, &path->p[i], &path->p[i + 1]); tmp = DatumGetFloat8(DirectFunctionCall2(dist_ps, PointPGetDatum(pt), LsegPGetDatum(&lseg))); if (i == 0 || tmp < result) result = tmp; } break; } PG_RETURN_FLOAT8(result); }