PostGIS  3.0.0dev-r@@SVN_REVISION@@

◆ lw_arc_calculate_gbox_cartesian_2d()

int lw_arc_calculate_gbox_cartesian_2d ( const POINT2D A1,
const POINT2D A2,
const POINT2D A3,
GBOX gbox 
)

Definition at line 459 of file g_box.c.

References FP_MAX, FP_MIN, lw_arc_center(), lw_segment_side(), LW_SUCCESS, LWDEBUG, POINT2D::x, GBOX::xmax, GBOX::xmin, POINT2D::y, GBOX::ymax, and GBOX::ymin.

Referenced by lw_arc_calculate_gbox_cartesian(), ptarrayarc_contains_point_partial(), and rect_node_leaf_new().

460 {
461  POINT2D xmin, ymin, xmax, ymax;
462  POINT2D C;
463  int A2_side;
464  double radius_A;
465 
466  LWDEBUG(2, "lw_arc_calculate_gbox_cartesian_2d called.");
467 
468  radius_A = lw_arc_center(A1, A2, A3, &C);
469 
470  /* Negative radius signals straight line, p1/p2/p3 are collinear */
471  if (radius_A < 0.0)
472  {
473  gbox->xmin = FP_MIN(A1->x, A3->x);
474  gbox->ymin = FP_MIN(A1->y, A3->y);
475  gbox->xmax = FP_MAX(A1->x, A3->x);
476  gbox->ymax = FP_MAX(A1->y, A3->y);
477  return LW_SUCCESS;
478  }
479 
480  /* Matched start/end points imply circle */
481  if ( A1->x == A3->x && A1->y == A3->y )
482  {
483  gbox->xmin = C.x - radius_A;
484  gbox->ymin = C.y - radius_A;
485  gbox->xmax = C.x + radius_A;
486  gbox->ymax = C.y + radius_A;
487  return LW_SUCCESS;
488  }
489 
490  /* First approximation, bounds of start/end points */
491  gbox->xmin = FP_MIN(A1->x, A3->x);
492  gbox->ymin = FP_MIN(A1->y, A3->y);
493  gbox->xmax = FP_MAX(A1->x, A3->x);
494  gbox->ymax = FP_MAX(A1->y, A3->y);
495 
496  /* Create points for the possible extrema */
497  xmin.x = C.x - radius_A;
498  xmin.y = C.y;
499  ymin.x = C.x;
500  ymin.y = C.y - radius_A;
501  xmax.x = C.x + radius_A;
502  xmax.y = C.y;
503  ymax.x = C.x;
504  ymax.y = C.y + radius_A;
505 
506  /* Divide the circle into two parts, one on each side of a line
507  joining p1 and p3. The circle extrema on the same side of that line
508  as p2 is on, are also the extrema of the bbox. */
509 
510  A2_side = lw_segment_side(A1, A3, A2);
511 
512  if ( A2_side == lw_segment_side(A1, A3, &xmin) )
513  gbox->xmin = xmin.x;
514 
515  if ( A2_side == lw_segment_side(A1, A3, &ymin) )
516  gbox->ymin = ymin.y;
517 
518  if ( A2_side == lw_segment_side(A1, A3, &xmax) )
519  gbox->xmax = xmax.x;
520 
521  if ( A2_side == lw_segment_side(A1, A3, &ymax) )
522  gbox->ymax = ymax.y;
523 
524  return LW_SUCCESS;
525 }
double lw_arc_center(const POINT2D *p1, const POINT2D *p2, const POINT2D *p3, POINT2D *result)
Determines the center of the circle defined by the three given points.
Definition: lwalgorithm.c:228
double xmax
Definition: liblwgeom.h:295
#define LW_SUCCESS
Definition: liblwgeom.h:79
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define FP_MIN(A, B)
double x
Definition: liblwgeom.h:330
double ymin
Definition: liblwgeom.h:296
double xmin
Definition: liblwgeom.h:294
double ymax
Definition: liblwgeom.h:297
double y
Definition: liblwgeom.h:330
int lw_segment_side(const POINT2D *p1, const POINT2D *p2, const POINT2D *q)
lw_segment_side()
Definition: lwalgorithm.c:64
#define FP_MAX(A, B)
Here is the call graph for this function:
Here is the caller graph for this function: