/* angles from center once a1 is rotated to zero */
double r2, r3;
double xe = 0.0, ye = 0.0;
- POINT4D *center;
+ POINT4D center;
int i;
LWDEBUG(2, "lwcircle_calculate_gbox called.");
radius = lwcircle_center(&p1, &p2, &p3, ¢er);
- if (radius < 0.0) return LW_FAILURE;
+ if (radius < 0.0) /* p1,p2,p3 are colinear */
+ {
+ gbox->xmin = FP_MIN(p1.x, p3.x);
+ gbox->ymin = FP_MIN(p1.y, p3.y);
+ gbox->zmin = FP_MIN(p1.z, p3.z);
+ gbox->xmax = FP_MAX(p1.x, p3.x);
+ gbox->ymax = FP_MAX(p1.y, p3.y);
+ gbox->zmax = FP_MAX(p1.z, p3.z);
+ return LW_SUCCESS;
+ }
x1 = MAXFLOAT;
x2 = -1 * MAXFLOAT;
y1 = MAXFLOAT;
y2 = -1 * MAXFLOAT;
- a1 = atan2(p1.y - center->y, p1.x - center->x);
- a2 = atan2(p2.y - center->y, p2.x - center->x);
- a3 = atan2(p3.y - center->y, p3.x - center->x);
+ a1 = atan2(p1.y - center.y, p1.x - center.x);
+ a2 = atan2(p2.y - center.y, p2.x - center.x);
+ a3 = atan2(p3.y - center.y, p3.x - center.x);
/* Rotate a2 and a3 such that a1 = 0 */
r2 = a2 - a1;
/* right extent */
case 0:
angle = 0.0;
- xe = center->x + radius;
- ye = center->y;
+ xe = center.x + radius;
+ ye = center.y;
break;
/* top extent */
case 1:
angle = M_PI_2;
- xe = center->x;
- ye = center->y + radius;
+ xe = center.x;
+ ye = center.y + radius;
break;
/* left extent */
case 2:
angle = M_PI;
- xe = center->x - radius;
- ye = center->y;
+ xe = center.x - radius;
+ ye = center.y;
break;
/* bottom extent */
case 3:
angle = -1 * M_PI_2;
- xe = center->x;
- ye = center->y - radius;
+ xe = center.x;
+ ye = center.y - radius;
break;
/* first point */
case 4:
******************************************************************************/
int lwgeom_has_arc(const LWGEOM *geom);
-double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
+double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *result);
LWGEOM *lwgeom_segmentize(LWGEOM *geom, uint32 perQuad);
LWGEOM *lwgeom_desegmentize(LWGEOM *geom);
-double lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result);
#endif /* !defined _LIBLWGEOM_H */
/* angles from center once a1 is rotated to zero */
double r2, r3;
double xe = 0.0, ye = 0.0;
- POINT4D *center;
+ POINT4D center;
int i;
BOX3D *box;
LWDEBUG(2, "lwcircle_compute_box3d called.");
- center = lwalloc(sizeof(POINT4D));
+ box = lwalloc(sizeof(BOX3D));
radius = lwcircle_center(p1, p2, p3, ¢er);
- if (radius < 0.0) return NULL;
+ if (radius < 0.0)
+ {
+ box->xmin = FP_MIN(p1->x, p3->x);
+ box->ymin = FP_MIN(p1->y, p3->y);
+ box->zmin = FP_MIN(p1->z, p3->z);
+ box->xmax = FP_MAX(p1->x, p3->x);
+ box->ymax = FP_MAX(p1->y, p3->y);
+ box->zmax = FP_MAX(p1->z, p3->z);
+ return box;
+ }
/*
- top = center->y + radius;
- left = center->x - radius;
+ top = center.y + radius;
+ left = center.x - radius;
- LWDEBUGF(3, "lwcircle_compute_box3d: center (%.16f, %.16f)", center->x, center->y);
+ LWDEBUGF(3, "lwcircle_compute_box3d: center (%.16f, %.16f)", center.x, center.y);
*/
x1 = MAXFLOAT;
y1 = MAXFLOAT;
y2 = -1 * MAXFLOAT;
- a1 = atan2(p1->y - center->y, p1->x - center->x);
- a2 = atan2(p2->y - center->y, p2->x - center->x);
- a3 = atan2(p3->y - center->y, p3->x - center->x);
+ a1 = atan2(p1->y - center.y, p1->x - center.x);
+ a2 = atan2(p2->y - center.y, p2->x - center.x);
+ a3 = atan2(p3->y - center.y, p3->x - center.x);
/* Rotate a2 and a3 such that a1 = 0 */
r2 = a2 - a1;
/* right extent */
case 0:
angle = 0.0;
- xe = center->x + radius;
- ye = center->y;
+ xe = center.x + radius;
+ ye = center.y;
break;
/* top extent */
case 1:
angle = M_PI_2;
- xe = center->x;
- ye = center->y + radius;
+ xe = center.x;
+ ye = center.y + radius;
break;
/* left extent */
case 2:
angle = M_PI;
- xe = center->x - radius;
- ye = center->y;
+ xe = center.x - radius;
+ ye = center.y;
break;
/* bottom extent */
case 3:
angle = -1 * M_PI_2;
- xe = center->x;
- ye = center->y - radius;
+ xe = center.x;
+ ye = center.y - radius;
break;
/* first point */
case 4:
LWDEBUGF(3, "lwcircle_compute_box3d: extreames found (%.16f %.16f, %.16f %.16f)", x1, y1, x2, y2);
/*
- x1 = center->x + x1 * radius;
- x2 = center->x + x2 * radius;
- y1 = center->y + y1 * radius;
- y2 = center->y + y2 * radius;
+ x1 = center.x + x1 * radius;
+ x2 = center.x + x2 * radius;
+ y1 = center.y + y1 * radius;
+ y2 = center.y + y2 * radius;
*/
z1 = (FP_LT(p1->z, p2->z)) ? p1->z : p2->z;
z1 = (FP_LT(z1, p3->z)) ? z1 : p3->z;
z2 = (FP_GT(p1->z, p2->z)) ? p1->z : p2->z;
z2 = (FP_GT(z2, p3->z)) ? z2 : p3->z;
- box = lwalloc(sizeof(BOX3D));
box->xmin = x1;
box->xmax = x2;
box->ymin = y1;
box->zmin = z1;
box->zmax = z2;
- lwfree(center);
-
return box;
}
* point is coincident with either end point, they are taken as colinear.
*/
double
-lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D **result)
+lwcircle_center(POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *result)
{
- POINT4D *c;
+ POINT4D c;
double cx, cy, cr;
double temp, bc, cd, det;
+ c.x = c.y = c.z = c.m = 0.0;
+
LWDEBUGF(2, "lwcircle_center called (%.16f, %.16f), (%.16f, %.16f), (%.16f, %.16f).", p1->x, p1->y, p2->x, p2->y, p3->x, p3->y);
/* Closed circle */
{
cx = p1->x + (p2->x - p1->x) / 2.0;
cy = p1->y + (p2->y - p1->y) / 2.0;
- c = lwalloc(sizeof(POINT2D));
- c->x = cx;
- c->y = cy;
+ c.x = cx;
+ c.y = cy;
*result = c;
cr = sqrt((cx-p1->x)*(cx-p1->x)+(cy-p1->y)*(cy-p1->y));
return cr;
/* Check colinearity */
if (fabs(det) < EPSILON_SQLMM)
- {
- *result = NULL;
return -1.0;
- }
+
det = 1.0 / det;
cx = (bc*(p2->y - p3->y)-cd*(p1->y - p2->y))*det;
cy = ((p1->x - p2->x)*cd-(p2->x - p3->x)*bc)*det;
- c = lwalloc(sizeof(POINT4D));
- c->x = cx;
- c->y = cy;
+ c.x = cx;
+ c.y = cy;
*result = c;
cr = sqrt((cx-p1->x)*(cx-p1->x)+(cy-p1->y)*(cy-p1->y));
return cr;
uint32 ptcount;
uchar *pt;
- POINT4D *center;
+ POINT4D center;
double radius = 0.0,
sweep = 0.0,
angle = 0.0,
return NULL;
}
- LWDEBUGF(3, "lwcircle_segmentize, (%.16f, %.16f) radius=%.16f", center->x, center->y, radius);
+ LWDEBUGF(3, "lwcircle_segmentize, (%.16f, %.16f) radius=%.16f", center.x, center.y, radius);
- a1 = atan2(p1->y - center->y, p1->x - center->x);
- a2 = atan2(p2->y - center->y, p2->x - center->x);
- a3 = atan2(p3->y - center->y, p3->x - center->x);
+ a1 = atan2(p1->y - center.y, p1->x - center.x);
+ a2 = atan2(p2->y - center.y, p2->x - center.x);
+ a3 = atan2(p3->y - center.y, p3->x - center.x);
LWDEBUGF(3, "a1 = %.16f, a2 = %.16f, a3 = %.16f", a1, a2, a3);
angle += increment;
if (increment > 0.0 && angle > M_PI) angle -= 2*M_PI;
if (increment < 0.0 && angle < -1*M_PI) angle -= 2*M_PI;
- pbuf.x = center->x + radius*cos(angle);
- pbuf.y = center->y + radius*sin(angle);
+ pbuf.x = center.x + radius*cos(angle);
+ pbuf.y = center.y + radius*sin(angle);
if ((sweep > 0 && angle < a2) || (sweep < 0 && angle > a2))
{
if ((sweep > 0 && a1 < a2) || (sweep < 0 && a1 > a2))
pt = getPoint_internal(result, ptcount - 1);
memcpy(pt, (uchar *)p3, ptsize);
- lwfree(center);
-
return result;
}
DROP TABLE foo;
+-- #668 --
+select '#668',box2d('CIRCULARSTRING(10 2,12 2,14 2)'::geometry) as b;
+
-- Clean up
DELETE FROM spatial_ref_sys;
#884|1|f
#884|2|t
#938|
+#668|BOX(10 2,14 2)