Skip to content

Commit e740d2c

Browse files
committed
Add spoly_is_convex
1 parent 710b338 commit e740d2c

File tree

9 files changed

+138
-10
lines changed

9 files changed

+138
-10
lines changed

Diff for: doc/functions.sgm

+26-1
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,32 @@
532532
</example>
533533

534534
</sect3>
535-
535+
<sect3 id="funcs.spoly.isconvex">
536+
<title>
537+
Spoly is convex
538+
</title>
539+
<para>
540+
Returns true if the specified spherical polygon is convex.
541+
Returns false otherwise.
542+
</para>
543+
<funcsynopsis>
544+
<funcprototype>
545+
<funcdef><function>spoly_is_convex</function></funcdef>
546+
<paramdef>spoly <parameter>polygon</parameter></paramdef>
547+
</funcprototype>
548+
</funcsynopsis>
549+
<example>
550+
<title>Check if polygon is convex</title>
551+
<programlisting>
552+
<![CDATA[sql> SELECT spoly_is_convex( spoly '{(0,0),(1,0),(1,1),(1,2)}' );]]>
553+
<![CDATA[ spoly_is_convex]]>
554+
<![CDATA[-----------------]]>
555+
<![CDATA[ t]]>
556+
<![CDATA[ (1 row)]]>
557+
</programlisting>
558+
</example>
559+
</sect3>
560+
536561
</sect2>
537562

538563
<sect2 id="funcs.sbox">

Diff for: expected/init_test.out.in

+7-7
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell
2424
psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined
2525
DETAIL: Creating a shell type definition.
2626
psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell
27-
psql:pg_sphere.test.sql:8568: NOTICE: type "spherekey" is not yet defined
27+
psql:pg_sphere.test.sql:8582: NOTICE: type "spherekey" is not yet defined
2828
DETAIL: Creating a shell type definition.
29-
psql:pg_sphere.test.sql:8575: NOTICE: argument type spherekey is only a shell
30-
psql:pg_sphere.test.sql:8589: NOTICE: type "pointkey" is not yet defined
29+
psql:pg_sphere.test.sql:8589: NOTICE: argument type spherekey is only a shell
30+
psql:pg_sphere.test.sql:8603: NOTICE: type "pointkey" is not yet defined
3131
DETAIL: Creating a shell type definition.
32-
psql:pg_sphere.test.sql:8596: NOTICE: argument type pointkey is only a shell
33-
psql:pg_sphere.test.sql:8602: NOTICE: argument type pointkey is only a shell
34-
psql:pg_sphere.test.sql:8608: NOTICE: argument type pointkey is only a shell
35-
psql:pg_sphere.test.sql:8614: NOTICE: argument type pointkey is only a shell
32+
psql:pg_sphere.test.sql:8610: NOTICE: argument type pointkey is only a shell
33+
psql:pg_sphere.test.sql:8616: NOTICE: argument type pointkey is only a shell
34+
psql:pg_sphere.test.sql:8622: NOTICE: argument type pointkey is only a shell
35+
psql:pg_sphere.test.sql:8628: NOTICE: argument type pointkey is only a shell

Diff for: expected/init_test_healpix.out.in

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
psql:pg_sphere.test.sql:9181: NOTICE: return type smoc is only a shell
2-
psql:pg_sphere.test.sql:9187: NOTICE: argument type smoc is only a shell
1+
psql:pg_sphere.test.sql:9195: NOTICE: return type smoc is only a shell
2+
psql:pg_sphere.test.sql:9201: NOTICE: argument type smoc is only a shell

Diff for: expected/poly.out

+19
Original file line numberDiff line numberDiff line change
@@ -1760,3 +1760,22 @@ SELECT npoints( spoly '{
17601760
4
17611761
(1 row)
17621762

1763+
-- spoly is convex
1764+
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) }');
1765+
spoly_is_convex
1766+
-----------------
1767+
f
1768+
(1 row)
1769+
1770+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}');
1771+
spoly_is_convex
1772+
-----------------
1773+
f
1774+
(1 row)
1775+
1776+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}');
1777+
spoly_is_convex
1778+
-----------------
1779+
t
1780+
(1 row)
1781+

Diff for: pgs_polygon.sql.in

+14
Original file line numberDiff line numberDiff line change
@@ -955,3 +955,17 @@ CREATE AGGREGATE spoly (
955955
stype = spoly,
956956
finalfunc = spoly_add_points_fin_aggr
957957
);
958+
959+
960+
--
961+
-- polygon is convex
962+
--
963+
964+
CREATE FUNCTION spoly_is_convex(spoly)
965+
RETURNS BOOL
966+
AS 'MODULE_PATHNAME', 'spherepoly_is_convex'
967+
LANGUAGE 'c'
968+
IMMUTABLE STRICT PARALLEL SAFE;
969+
970+
COMMENT ON FUNCTION spoly_is_convex(spoly) IS
971+
'true if spherical polygon is convex';

Diff for: sql/poly.sql

+5
Original file line numberDiff line numberDiff line change
@@ -603,3 +603,8 @@ SELECT npoints( spoly '{
603603
(1.5121581120647 , -1.93925472462553e-05),
604604
(1.51214841579108 , -1.93925472462553e-05)
605605
}');
606+
607+
-- spoly is convex
608+
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) }');
609+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}');
610+
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}');

Diff for: src/polygon.c

+51
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ PG_FUNCTION_INFO_V1(spheretrans_poly);
5757
PG_FUNCTION_INFO_V1(spheretrans_poly_inverse);
5858
PG_FUNCTION_INFO_V1(spherepoly_add_point);
5959
PG_FUNCTION_INFO_V1(spherepoly_add_points_finalize);
60+
PG_FUNCTION_INFO_V1(spherepoly_is_convex);
6061

6162

6263
/*
@@ -1478,3 +1479,53 @@ spherepoly_add_points_finalize(PG_FUNCTION_ARGS)
14781479
}
14791480
PG_RETURN_POINTER(poly);
14801481
}
1482+
1483+
1484+
Datum
1485+
spherepoly_is_convex(PG_FUNCTION_ARGS)
1486+
{
1487+
Vector3D u,
1488+
v,
1489+
vsu,
1490+
wsv,
1491+
crs;
1492+
float8 cur = 0.0,
1493+
prev = 0.0;
1494+
SPOLY *poly = (SPOLY *) PG_GETARG_POINTER(0);
1495+
1496+
if (poly == NULL)
1497+
{
1498+
PG_RETURN_BOOL(false);
1499+
}
1500+
1501+
poly = PG_GETARG_SPOLY(0);
1502+
if (poly->npts == 3)
1503+
{
1504+
PG_RETURN_BOOL(true);
1505+
}
1506+
1507+
for (int i = 0; i < poly->npts; i++)
1508+
{
1509+
const int j = (i - 1 + poly->npts) % poly->npts;
1510+
const int k = (i + 1) % poly->npts;
1511+
1512+
spoint_vector3d(&u, &poly->p[i]);
1513+
spoint_vector3d(&v, &poly->p[j]);
1514+
spoint_vector3d(&vsu, &poly->p[j]);
1515+
spoint_vector3d(&wsv, &poly->p[k]);
1516+
1517+
vector3d_addwithscalar(&vsu, -1, &u);
1518+
vector3d_addwithscalar(&wsv, -1, &v);
1519+
1520+
vector3d_cross(&crs, &vsu, &wsv);
1521+
1522+
cur = vector3d_scalar(&crs, &v);
1523+
if (cur * prev < 0)
1524+
{
1525+
PG_RETURN_BOOL(false);
1526+
}
1527+
prev = cur;
1528+
}
1529+
1530+
PG_RETURN_BOOL(true);
1531+
}

Diff for: src/polygon.h

+5
Original file line numberDiff line numberDiff line change
@@ -348,4 +348,9 @@ Datum spherepoly_add_point(PG_FUNCTION_ARGS);
348348
*/
349349
Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS);
350350

351+
/*
352+
* Checks whether a polygon is convex
353+
*/
354+
Datum spherepoly_is_convex(PG_FUNCTION_ARGS);
355+
351356
#endif

Diff for: upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in

+9
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,12 @@ COMMENT ON FUNCTION spoly_deg(float8[]) IS
2727
Two consecutive numbers among those present
2828
refer to the same occurrence and cover its
2929
latitude and longitude, respectively.';
30+
31+
CREATE FUNCTION spoly_is_convex(spoly)
32+
RETURNS BOOL
33+
AS 'MODULE_PATHNAME', 'spherepoly_is_convex'
34+
LANGUAGE 'c'
35+
IMMUTABLE STRICT PARALLEL SAFE;
36+
37+
COMMENT ON FUNCTION spoly_is_convex(spoly) IS
38+
'true if spherical polygon is convex';

0 commit comments

Comments
 (0)