Skip to content

Commit d89edcf

Browse files
committed
add spoly_is_convex
1 parent 612f06b commit d89edcf

File tree

7 files changed

+141
-7
lines changed

7 files changed

+141
-7
lines changed

Diff for: expected/init_test.out

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
SET client_min_messages TO NOTICE;
2+
\set ECHO none
3+
psql:pg_sphere.test.sql:9: NOTICE: type "spoint" is not yet defined
4+
DETAIL: Creating a shell type definition.
5+
psql:pg_sphere.test.sql:16: NOTICE: argument type spoint is only a shell
6+
psql:pg_sphere.test.sql:32: NOTICE: type "strans" is not yet defined
7+
DETAIL: Creating a shell type definition.
8+
psql:pg_sphere.test.sql:39: NOTICE: argument type strans is only a shell
9+
psql:pg_sphere.test.sql:55: NOTICE: type "scircle" is not yet defined
10+
DETAIL: Creating a shell type definition.
11+
psql:pg_sphere.test.sql:62: NOTICE: argument type scircle is only a shell
12+
psql:pg_sphere.test.sql:78: NOTICE: type "sline" is not yet defined
13+
DETAIL: Creating a shell type definition.
14+
psql:pg_sphere.test.sql:85: NOTICE: argument type sline is only a shell
15+
psql:pg_sphere.test.sql:101: NOTICE: type "sellipse" is not yet defined
16+
DETAIL: Creating a shell type definition.
17+
psql:pg_sphere.test.sql:108: NOTICE: argument type sellipse is only a shell
18+
psql:pg_sphere.test.sql:126: NOTICE: type "spoly" is not yet defined
19+
DETAIL: Creating a shell type definition.
20+
psql:pg_sphere.test.sql:133: NOTICE: argument type spoly is only a shell
21+
psql:pg_sphere.test.sql:152: NOTICE: type "spath" is not yet defined
22+
DETAIL: Creating a shell type definition.
23+
psql:pg_sphere.test.sql:159: NOTICE: argument type spath is only a shell
24+
psql:pg_sphere.test.sql:178: NOTICE: type "sbox" is not yet defined
25+
DETAIL: Creating a shell type definition.
26+
psql:pg_sphere.test.sql:185: NOTICE: argument type sbox is only a shell
27+
psql:pg_sphere.test.sql:8554: NOTICE: type "spherekey" is not yet defined
28+
DETAIL: Creating a shell type definition.
29+
psql:pg_sphere.test.sql:8561: NOTICE: argument type spherekey is only a shell
30+
psql:pg_sphere.test.sql:8575: NOTICE: type "pointkey" is not yet defined
31+
DETAIL: Creating a shell type definition.
32+
psql:pg_sphere.test.sql:8582: NOTICE: argument type pointkey is only a shell
33+
psql:pg_sphere.test.sql:8588: NOTICE: argument type pointkey is only a shell
34+
psql:pg_sphere.test.sql:8594: NOTICE: argument type pointkey is only a shell
35+
psql:pg_sphere.test.sql:8600: NOTICE: argument type pointkey is only a shell
36+
psql:pg_sphere.test.sql:9167: NOTICE: return type smoc is only a shell
37+
psql:pg_sphere.test.sql:9173: NOTICE: argument type smoc is only a shell

Diff for: expected/init_test.out.in

+9-7
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ psql:pg_sphere.test.sql:159: NOTICE: argument type spath is only a shell
2424
psql:pg_sphere.test.sql:178: NOTICE: type "sbox" is not yet defined
2525
DETAIL: Creating a shell type definition.
2626
psql:pg_sphere.test.sql:185: NOTICE: argument type sbox is only a shell
27-
psql:pg_sphere.test.sql:8540: NOTICE: type "spherekey" is not yet defined
27+
psql:pg_sphere.test.sql:8554: NOTICE: type "spherekey" is not yet defined
2828
DETAIL: Creating a shell type definition.
29-
psql:pg_sphere.test.sql:8547: NOTICE: argument type spherekey is only a shell
30-
psql:pg_sphere.test.sql:8561: NOTICE: type "pointkey" is not yet defined
29+
psql:pg_sphere.test.sql:8561: NOTICE: argument type spherekey is only a shell
30+
psql:pg_sphere.test.sql:8575: NOTICE: type "pointkey" is not yet defined
3131
DETAIL: Creating a shell type definition.
32-
psql:pg_sphere.test.sql:8568: NOTICE: argument type pointkey is only a shell
33-
psql:pg_sphere.test.sql:8574: NOTICE: argument type pointkey is only a shell
34-
psql:pg_sphere.test.sql:8580: NOTICE: argument type pointkey is only a shell
35-
psql:pg_sphere.test.sql:8586: NOTICE: argument type pointkey is only a shell
32+
psql:pg_sphere.test.sql:8582: NOTICE: argument type pointkey is only a shell
33+
psql:pg_sphere.test.sql:8588: NOTICE: argument type pointkey is only a shell
34+
psql:pg_sphere.test.sql:8594: NOTICE: argument type pointkey is only a shell
35+
psql:pg_sphere.test.sql:8600: NOTICE: argument type pointkey is only a shell
36+
psql:pg_sphere.test.sql:9167: NOTICE: return type smoc is only a shell
37+
psql:pg_sphere.test.sql:9173: NOTICE: argument type smoc is only a shell

Diff for: expected/poly.out

+19
Original file line numberDiff line numberDiff line change
@@ -1738,3 +1738,22 @@ SELECT npoints( spoly '{
17381738
4
17391739
(1 row)
17401740

1741+
-- spoly is convex
1742+
SELECT spoly_is_convex(spoly'{(53d 45m 35.0s, 37d 6m 30.0s), (52d 21m 36.0s, 41d 36m 7.0s), (54d 14m 18.0s, 45d 1m 35.0s), (51d 23m 3.0s, 45d 22m 49.0s), (51d 2m 12.0s, 41d 52m 1.0s), (50d 41m 47.0s, 38d 22m 0s) }');
1743+
spoly_is_convex
1744+
-----------------
1745+
f
1746+
(1 row)
1747+
1748+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}');
1749+
spoly_is_convex
1750+
-----------------
1751+
f
1752+
(1 row)
1753+
1754+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}');
1755+
spoly_is_convex
1756+
-----------------
1757+
t
1758+
(1 row)
1759+

Diff for: pgs_polygon.sql.in

+14
Original file line numberDiff line numberDiff line change
@@ -943,3 +943,17 @@ CREATE AGGREGATE spoly (
943943
stype = spoly,
944944
finalfunc = spoly_add_points_fin_aggr
945945
);
946+
947+
948+
--
949+
-- polygon is convex
950+
--
951+
952+
CREATE FUNCTION spoly_is_convex(spoly)
953+
RETURNS BOOL
954+
AS 'MODULE_PATHNAME', 'spherepoly_is_convex'
955+
LANGUAGE 'c'
956+
IMMUTABLE STRICT PARALLEL SAFE;
957+
958+
COMMENT ON FUNCTION spoly_is_convex(spoly) IS
959+
'true if spherical polygon is convex';

Diff for: sql/poly.sql

+5
Original file line numberDiff line numberDiff line change
@@ -593,3 +593,8 @@ SELECT npoints( spoly '{
593593
(1.5121581120647 , -1.93925472462553e-05),
594594
(1.51214841579108 , -1.93925472462553e-05)
595595
}');
596+
597+
-- spoly is convex
598+
SELECT spoly_is_convex(spoly'{(53d 45m 35.0s, 37d 6m 30.0s), (52d 21m 36.0s, 41d 36m 7.0s), (54d 14m 18.0s, 45d 1m 35.0s), (51d 23m 3.0s, 45d 22m 49.0s), (51d 2m 12.0s, 41d 52m 1.0s), (50d 41m 47.0s, 38d 22m 0s) }');
599+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}');
600+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}');

Diff for: src/polygon.c

+52
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ PG_FUNCTION_INFO_V1(spheretrans_poly);
5555
PG_FUNCTION_INFO_V1(spheretrans_poly_inverse);
5656
PG_FUNCTION_INFO_V1(spherepoly_add_point);
5757
PG_FUNCTION_INFO_V1(spherepoly_add_points_finalize);
58+
PG_FUNCTION_INFO_V1(spherepoly_is_convex);
5859

5960

6061
/*
@@ -1431,3 +1432,54 @@ spherepoly_add_points_finalize(PG_FUNCTION_ARGS)
14311432
}
14321433
PG_RETURN_POINTER(poly);
14331434
}
1435+
1436+
1437+
Datum
1438+
spherepoly_is_convex(PG_FUNCTION_ARGS)
1439+
{
1440+
Vector3D u,
1441+
v,
1442+
vsu,
1443+
wsv,
1444+
crs;
1445+
float8 cur = 0,
1446+
prev = 0;
1447+
SPOLY *poly = (SPOLY *) PG_GETARG_POINTER(0);
1448+
1449+
if (poly == NULL)
1450+
{
1451+
PG_RETURN_NULL();
1452+
}
1453+
1454+
poly = PG_GETARG_SPOLY(0);
1455+
if (poly->npts == 3)
1456+
{
1457+
PG_RETURN_BOOL(true);
1458+
}
1459+
1460+
for (int i = 0; i < poly->npts; i++)
1461+
{
1462+
int j = (i - 1 + poly->npts) % poly->npts;
1463+
int k = (i + 1) % poly->npts;
1464+
1465+
spoint_vector3d(&u, &poly->p[i]);
1466+
spoint_vector3d(&v, &poly->p[j]);
1467+
spoint_vector3d(&vsu, &poly->p[j]);
1468+
spoint_vector3d(&wsv, &poly->p[k]);
1469+
1470+
vector3d_addwithscalar(&vsu, -1, &u);
1471+
vector3d_addwithscalar(&wsv, -1, &v);
1472+
1473+
vector3d_cross(&crs, &vsu, &wsv);
1474+
1475+
cur = vector3d_scalar(&crs, &v);
1476+
if (cur * prev < 0)
1477+
{
1478+
PG_RETURN_BOOL(false);
1479+
}
1480+
prev = cur;
1481+
1482+
}
1483+
1484+
PG_RETURN_BOOL(true);
1485+
}

Diff for: src/polygon.h

+5
Original file line numberDiff line numberDiff line change
@@ -343,4 +343,9 @@ Datum spherepoly_add_point(PG_FUNCTION_ARGS);
343343
*/
344344
Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS);
345345

346+
/*
347+
* Checks whether a polygon is convex
348+
*/
349+
Datum spherepoly_is_convex(PG_FUNCTION_ARGS);
350+
346351
#endif

0 commit comments

Comments
 (0)