PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ edge_calculate_gbox()

int edge_calculate_gbox ( const POINT3D A1,
const POINT3D A2,
GBOX gbox 
)

The magic function, given an edge in spherical coordinates, calculate a 3D bounding box that fully contains it, taking into account the curvature of the sphere on which it is inscribed.

Any arc on the sphere defines a plane that bisects the sphere. In this plane, the arc is a portion of a unit circle. Projecting the end points of the axes (1,0,0), (-1,0,0) etc, into the plane and normalizing yields potential extrema points. Those points on the side of the plane-dividing line formed by the end points that is opposite the origin of the plane are extrema and should be added to the bounding box.

Definition at line 1362 of file lwgeodetic.c.

1363{
1364 POINT2D R1, R2, RX, O;
1365 POINT3D AN, A3;
1366 POINT3D X[6];
1367 int i, o_side;
1368
1369 /* Initialize the box with the edge end points */
1370 gbox_init_point3d(A1, gbox);
1371 gbox_merge_point3d(A2, gbox);
1372
1373 /* Zero length edge, just return! */
1374 if ( p3d_same(A1, A2) )
1375 return LW_SUCCESS;
1376
1377 /* Error out on antipodal edge */
1378 if ( FP_EQUALS(A1->x, -1*A2->x) && FP_EQUALS(A1->y, -1*A2->y) && FP_EQUALS(A1->z, -1*A2->z) )
1379 {
1380 lwerror("Antipodal (180 degrees long) edge detected!");
1381 return LW_FAILURE;
1382 }
1383
1384 /* Create A3, a vector in the plane of A1/A2, orthogonal to A1 */
1385 unit_normal(A1, A2, &AN);
1386 unit_normal(&AN, A1, &A3);
1387
1388 /* Project A1 and A2 into the 2-space formed by the plane A1/A3 */
1389 R1.x = 1.0;
1390 R1.y = 0.0;
1391 R2.x = dot_product(A2, A1);
1392 R2.y = dot_product(A2, &A3);
1393
1394 /* Initialize our 3-space axis points (x+, x-, y+, y-, z+, z-) */
1395 memset(X, 0, sizeof(POINT3D) * 6);
1396 X[0].x = X[2].y = X[4].z = 1.0;
1397 X[1].x = X[3].y = X[5].z = -1.0;
1398
1399 /* Initialize a 2-space origin point. */
1400 O.x = O.y = 0.0;
1401 /* What side of the line joining R1/R2 is O? */
1402 o_side = lw_segment_side(&R1, &R2, &O);
1403
1404 /* Add any extrema! */
1405 for ( i = 0; i < 6; i++ )
1406 {
1407 /* Convert 3-space axis points to 2-space unit vectors */
1408 RX.x = dot_product(&(X[i]), A1);
1409 RX.y = dot_product(&(X[i]), &A3);
1410 normalize2d(&RX);
1411
1412 /* Any axis end on the side of R1/R2 opposite the origin */
1413 /* is an extreme point in the arc, so we add the 3-space */
1414 /* version of the point on R1/R2 to the gbox */
1415 if ( lw_segment_side(&R1, &R2, &RX) != o_side )
1416 {
1417 POINT3D Xn;
1418 Xn.x = RX.x * A1->x + RX.y * A3.x;
1419 Xn.y = RX.x * A1->y + RX.y * A3.y;
1420 Xn.z = RX.x * A1->z + RX.y * A3.z;
1421
1422 gbox_merge_point3d(&Xn, gbox);
1423 }
1424 }
1425
1426 return LW_SUCCESS;
1427}
int gbox_merge_point3d(const POINT3D *p, GBOX *gbox)
Update the GBOX to be large enough to include itself and the new point.
Definition gbox.c:228
int gbox_init_point3d(const POINT3D *p, GBOX *gbox)
Initialize a GBOX using the values of the point.
Definition gbox.c:239
#define LW_FAILURE
Definition liblwgeom.h:96
#define LW_SUCCESS
Definition liblwgeom.h:97
int p3d_same(const POINT3D *p1, const POINT3D *p2)
Definition lwalgorithm.c:41
#define FP_EQUALS(A, B)
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition lwalgorithm.c:70
static void normalize2d(POINT2D *p)
Normalize to a unit vector.
Definition lwgeodetic.c:524
void unit_normal(const POINT3D *P1, const POINT3D *P2, POINT3D *normal)
Calculates the unit normal to two vectors, trying to avoid problems with over-narrow or over-wide cas...
Definition lwgeodetic.c:541
static double dot_product(const POINT3D *p1, const POINT3D *p2)
Convert cartesian coordinates on unit sphere to lon/lat coordinates static void cart2ll(const POINT3D...
Definition lwgeodetic.c:446
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
double z
Definition liblwgeom.h:402
double x
Definition liblwgeom.h:402
double y
Definition liblwgeom.h:402

References dot_product(), FP_EQUALS, gbox_init_point3d(), gbox_merge_point3d(), LW_FAILURE, lw_segment_side(), LW_SUCCESS, lwerror(), normalize2d(), p3d_same(), unit_normal(), POINT2D::x, POINT3D::x, POINT2D::y, POINT3D::y, and POINT3D::z.

Referenced by ptarray_calculate_gbox_geodetic().

Here is the call graph for this function:
Here is the caller graph for this function: