Skip to content

Add spoly_is_convex #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions doc/functions.sgm
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,33 @@
</programlisting>
</example>
</sect3>

<sect3 id="funcs.spoly.isconvex">
<title>
Spoly is convex
</title>
<para>
Returns true if the specified spherical polygon is convex.
Returns false otherwise.
</para>
<funcsynopsis>
<funcprototype>
<funcdef><function>spoly_is_convex</function></funcdef>
<paramdef>spoly <parameter>polygon</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<example>
<title>Check if polygon is convex</title>
<programlisting>
<![CDATA[sql> SELECT spoly_is_convex( spoly '{(0,0),(1,0),(1,1),(1,2)}' );]]>
<![CDATA[ spoly_is_convex]]>
<![CDATA[-----------------]]>
<![CDATA[ t]]>
<![CDATA[ (1 row)]]>
</programlisting>
</example>
</sect3>

</sect2>

<sect2 id="funcs.sbox">
Expand Down
14 changes: 7 additions & 7 deletions expected/init_test.out.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell
psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell
psql:pg_sphere.test.sql:8644: NOTICE: type "spherekey" is not yet defined
psql:pg_sphere.test.sql:8658: NOTICE: type "spherekey" is not yet defined
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:8651: NOTICE: argument type spherekey is only a shell
psql:pg_sphere.test.sql:8665: NOTICE: type "pointkey" is not yet defined
psql:pg_sphere.test.sql:8665: NOTICE: argument type spherekey is only a shell
psql:pg_sphere.test.sql:8679: NOTICE: type "pointkey" is not yet defined
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:8672: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8678: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8684: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8690: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8686: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8692: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8698: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8704: NOTICE: argument type pointkey is only a shell
4 changes: 2 additions & 2 deletions expected/init_test_healpix.out.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
psql:pg_sphere.test.sql:9257: NOTICE: return type smoc is only a shell
psql:pg_sphere.test.sql:9263: NOTICE: argument type smoc is only a shell
psql:pg_sphere.test.sql:9271: NOTICE: return type smoc is only a shell
psql:pg_sphere.test.sql:9277: NOTICE: argument type smoc is only a shell
25 changes: 25 additions & 0 deletions expected/poly.out
Original file line number Diff line number Diff line change
Expand Up @@ -1799,3 +1799,28 @@ SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );
{"(0 , 0)","(1 , 0)","(1 , 1)"}
(1 row)

-- spoly is convex
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) }');
spoly_is_convex
-----------------
f
(1 row)

SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}');
spoly_is_convex
-----------------
f
(1 row)

SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}');
spoly_is_convex
-----------------
t
(1 row)

SELECT spoly_is_convex(NULL);
spoly_is_convex
-----------------
f
(1 row)

14 changes: 14 additions & 0 deletions pgs_polygon.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -973,3 +973,17 @@ CREATE AGGREGATE spoly (
stype = spoly,
finalfunc = spoly_add_points_fin_aggr
);


--
-- polygon is convex
--

CREATE FUNCTION spoly_is_convex(spoly)
RETURNS BOOL
AS 'MODULE_PATHNAME', 'spherepoly_is_convex'
LANGUAGE 'c'
IMMUTABLE PARALLEL SAFE;

COMMENT ON FUNCTION spoly_is_convex(spoly) IS
'true if spherical polygon is convex';
6 changes: 6 additions & 0 deletions sql/poly.sql
Original file line number Diff line number Diff line change
Expand Up @@ -616,3 +616,9 @@ SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );
SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );

-- spoly is convex
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) }');
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}');
SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}');
SELECT spoly_is_convex(NULL);
52 changes: 52 additions & 0 deletions src/polygon.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ PG_FUNCTION_INFO_V1(spheretrans_poly);
PG_FUNCTION_INFO_V1(spheretrans_poly_inverse);
PG_FUNCTION_INFO_V1(spherepoly_add_point);
PG_FUNCTION_INFO_V1(spherepoly_add_points_finalize);
PG_FUNCTION_INFO_V1(spherepoly_is_convex);


/*
Expand Down Expand Up @@ -1531,3 +1532,54 @@ spherepoly_add_points_finalize(PG_FUNCTION_ARGS)
}
PG_RETURN_POINTER(poly);
}


Datum
spherepoly_is_convex(PG_FUNCTION_ARGS)
{
Vector3D u,
v,
vsu,
wsv,
crs;
int32 i;
float8 cur = 0.0,
prev = 0.0;
SPOLY *poly = (SPOLY *) PG_GETARG_POINTER(0);

if (poly == NULL)
{
PG_RETURN_BOOL(false);
}

poly = PG_GETARG_SPOLY(0);
if (poly->npts == 3)
{
PG_RETURN_BOOL(true);
}

for (i = 0; i < poly->npts; i++)
{
const int j = (i - 1 + poly->npts) % poly->npts;
const int k = (i + 1) % poly->npts;

spoint_vector3d(&u, &poly->p[i]);
spoint_vector3d(&v, &poly->p[j]);
spoint_vector3d(&vsu, &poly->p[j]);
spoint_vector3d(&wsv, &poly->p[k]);

vector3d_addwithscalar(&vsu, -1, &u);
vector3d_addwithscalar(&wsv, -1, &v);

vector3d_cross(&crs, &vsu, &wsv);

cur = vector3d_scalar(&crs, &v);
if (cur * prev < 0)
{
PG_RETURN_BOOL(false);
}
prev = cur;
}

PG_RETURN_BOOL(true);
}
5 changes: 5 additions & 0 deletions src/polygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,4 +358,9 @@ Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS);
*/
Datum spherepoly_get_array(PG_FUNCTION_ARGS);

/*
* Checks whether a polygon is convex
*/
Datum spherepoly_is_convex(PG_FUNCTION_ARGS);

#endif
9 changes: 9 additions & 0 deletions upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,12 @@ CREATE OPERATOR <-> (

COMMENT ON OPERATOR <-> (spoint, sline) IS
'returns the distance between spherical line and spherical point';

CREATE FUNCTION spoly_is_convex(spoly)
RETURNS BOOL
AS 'MODULE_PATHNAME', 'spherepoly_is_convex'
LANGUAGE 'c'
IMMUTABLE PARALLEL SAFE;

COMMENT ON FUNCTION spoly_is_convex(spoly) IS
'true if spherical polygon is convex';