[postgis-devel] Rotate functions

Mike Toews mwtoews at sfu.ca
Mon Jan 25 00:18:28 PST 2010


Hi,

I'm not sure if anyone has inspected the Rotate functions closely, but 
they are vaguely documented. Specifically, they don't specify the origin 
of the axis of rotation in the docs. Intuitively, one could assume it 
would be the centroid of the feature (as graphics programs, such as 
ArcGIS or Adobe Illustrator might have us think), but it is actually the 
absolute origin (0 0) ... as in latitude 0 or northing 0 m, etc.

The fundamentals of rotating objects in 2D requires two pieces of 
information: (1) the origin or coordinate of the axis of rotation; and 
(2) a rotation angle. These are required by CAD programs, and the origin 
of rotation is often adjustable in many graphics programs. However, 
ST_Rotate (et al.) only offer the rotation angle. I would expect the 
[ST_RotateZ] function to have two alternative definitions:

geometry ST_Rotate(geometry geomA, float x0, float y0, float rotRadians);
-- or --
geometry ST_Rotate(geometry geomA, geometry axisOrig, float rotRadians);

To apply some trigonometry to PostGIS, we can use the affine function 
with some modified offsets (not 0). Consider a polygon 'geom', rotated 
from (11 10) by -270 degrees:

SELECT asewkt(affine(geom,  cos(rad), -sin(rad), 0,  sin(rad), cos(rad), 
0, 0, 0, 1,  X0-cos(rad)*X0+sin(rad)*Y0, Y0-sin(rad)*X0-cos(rad)*Y0, 0))
FROM (select 'POLYGON((10 10, 11 10, 11 11, 10 10))'::geometry as geom, 
-270*2*pi()/360 as rad, 11 as X0, 10 as Y0) AS foo;

POLYGON((11 9,11 10,10 10,11 9))

This could be defined in the definitions described above as the 
following functions:

-- geometry ST_Rotate(geometry geomA, float x0, float y0, float rotRadians);
CREATE OR REPLACE FUNCTION st_rotate(geometry, double precision, double 
precision, double precision)
   RETURNS geometry AS
'SELECT affine($1, cos($4), -sin($4), 0, sin($4), cos($4), 0, 0, 0, 1, 
$2-cos($4)*$2+sin($4)*$3, $3-sin($4)*$2-cos($4)*$3, 0)' LANGUAGE 'sql' 
IMMUTABLE STRICT COST 100;

-- select asewkt(st_rotate('POLYGON((10 10, 11 10, 11 11, 10 
10))'::geometry, 11, 10, -270*2*pi()/360));

-- or --

-- geometry ST_Rotate(geometry geomA, geometry axisOrig, float rotRadians);
CREATE OR REPLACE FUNCTION st_rotate(geometry, geometry, double precision)
   RETURNS geometry AS
'SELECT affine($1, cos($3), -sin($3), 0, sin($3), cos($3), 0, 0, 0, 1, 
st_x($2)-cos($3)*st_x($2)+sin($3)*st_y($2), 
st_y($2)-sin($3)*st_x($2)-cos($3)*st_y($2), 0)' LANGUAGE 'sql' IMMUTABLE 
STRICT COST 100;

-- select asewkt(st_rotate('POLYGON((10 10, 11 10, 11 11, 10 
10))'::geometry, 'POINT(11 10)'::geometry, -270*2*pi()/360));

I'd pick the second of the two if I could make a decision on which to 
keep/loose.

Also, I figure it is for mathematical completeness, but why does the 
standard PostGIS install include rotateX and rotateY in the SQL 
functions? I consider this bloat, since I don't see who would use it 
(especially since they are all from x/y/z=0)? Primarily, GIS folk view 
maps from above. As a geologist, I often use depth in my day-to-day 
work, but I'd rarely see a need for rotating on anything but Z. Should 
these other rotation functions be deprecated and removed in a future 
release? As they depend on affine, they can always be included on a Wiki 
for odd-ball future reference, as they could always be in demand by 
someone for some purpose. But the same could be said for rotating on 
arbitrary XZ and YZ axes using similar functions as above for XY-plane 
rotations.

-Mike



More information about the postgis-devel mailing list