diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 6cb2467dca..90a2582dfd 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -9446,188 +9446,576 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple linkend="functions-geometry-conv-table"/>. + + Geometric Operators + + + + + OperatorDescriptionExample(s) + + + + + + + + geometric_type + point + geometric_type + + Adds the coordinates of the second point to those of each + point of the first argument, thus performing translation. + Available for point, box, path, + circle. + + box '(1,1),(0,0)' + point '(2,0)' + (3,1),(2,0) + + + + + + path + path + path + + Concatenates two open paths (returns NULL if either path is closed). + + path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' + [(0,0),(1,1),(2,2),(3,3),(4,4)] + + + + + + geometric_type - point + geometric_type + + Subtracts the coordinates of the second point from those + of each point of the first argument, thus performing translation. + Available for point, box, path, + circle. + + box '(1,1),(0,0)' - point '(2,0)' + (-1,1),(-2,0) + + + + + + geometric_type * point + geometric_type + + Multiplies each point of the first argument by the second + pointFor this purpose, the + product of two points + (x1,y1) and + (x2,y2) is + defined as + (x1*x2 - + y1*y2, + x1*y2 + + y1*x2).. + Interpreting the point as a vector, this is equivalent to + scaling the object's size and distance from the origin by the length + of the vector, and rotating it counterclockwise around the origin by + the vector's angle from the x axis. + Available for point, box, path, + circle. + + path '((0,0),(1,0),(1,1))' * point '(3.0,0)' + ((0,0),(3,0),(3,3)) + + path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45)) + ((0,0),&zwsp;(0.7071067811865475,0.7071067811865475),&zwsp;(0,1.414213562373095)) + + + + + + geometric_type / point + geometric_type + + Divides each point of the first argument by the + second pointFor this purpose, the + quotient of two points + (x1,y1) and + (x2,y2) is + defined as + ((x1*x2 + + y1*y2) / + L, + (y1*x2 - + x1*y2) / + L), + where L = + x2*x2 + + y2*y2.. + Interpreting the point as a vector, this is equivalent to + scaling the object's size and distance from the origin down by the + length of the vector, and rotating it clockwise around the origin by + the vector's angle from the x axis. + Available for point, box, path, + circle. + + path '((0,0),(1,0),(1,1))' / point '(2.0,0)' + ((0,0),(0.5,0),(0.5,0.5)) + + path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45)) + ((0,0),&zwsp;(0.7071067811865476,-0.7071067811865476),&zwsp;(1.4142135623730951,0)) + + + + + + @-@ geometric_type + double precision + + Computes the total length. + Available for lseg, path. + + @-@ path '[(0,0),(1,0),(1,1)]' + 2 + + + + + + @@ geometric_type + point + + Computes the center point. + Available for box, lseg, path, + polygon, circle. + + @@ box '(2,2),(0,0)' + (1,1) + + + + + + # geometric_type + integer + + Returns the number of points. + Available for path, polygon. + + # path '((1,0),(0,1),(-1,0))' + 3 + + + + + + geometric_type # geometric_type + point + + Computes the point of intersection, or NULL if there is none. + Available for lseg, line. + + lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]' + (0.5,0.5) + + + + + + box # box + box + + Computes the intersection of two boxes, or NULL if there is none. + + box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' + (1,1),(-1,-1) + + + + + + geometric_type ## geometric_type + point + + Computes the closest point to the first object on the second object. + Available for these pairs of types: + (point, box), + (point, lseg), + (point, line), + (lseg, box), + (lseg, lseg), + (lseg, line), + (line, box), + (line, lseg). + + point '(0,0)' ## lseg '[(2,0),(0,2)]' + (1,1) + + + + + + geometric_type <-> geometric_type + double precision + + Computes the distance between the objects. + Available for all seven geometric types, for all combinations + of point with another geometric type, and for + these additional pairs of types: + (box, lseg), + (box, line), + (lseg, line), + (polygon, circle) + (and the commutator cases). + + circle '<(0,0),1>' <-> circle '<(5,0),1>' + 3 + + + + + + geometric_type @> geometric_type + boolean + + Does first object contain second? + Available for these pairs of types: + (box, point), + (box, box), + (path, point), + (polygon, point), + (polygon, polygon), + (circle, point), + (circle, circle). + + circle '<(0,0),2>' @> point '(1,1)' + t + + + + + + geometric_type <@ geometric_type + boolean + + Is first object contained in or on second? + Available for these pairs of types: + (point, box), + (point, lseg), + (point, line), + (point, path), + (point, polygon), + (point, circle), + (box, box), + (lseg, box), + (lseg, line), + (polygon, polygon), + (circle, circle). + + point '(1,1)' <@ circle '<(0,0),2>' + t + + + + + + geometric_type && geometric_type + boolean + + Do these objects overlap? (One point in common makes this true.) + Available for box, polygon, + circle. + + box '(1,1),(0,0)' && box '(2,2),(0,0)' + t + + + + + + geometric_type << geometric_type + boolean + + Is first object strictly left of second? + Available for point, box, + polygon, circle. + + circle '<(0,0),1>' << circle '<(5,0),1>' + t + + + + + + geometric_type >> geometric_type + boolean + + Is first object strictly right of second? + Available for point, box, + polygon, circle. + + circle '<(5,0),1>' >> circle '<(0,0),1>' + t + + + + + + geometric_type &< geometric_type + boolean + + Does first object not extend to the right of second? + Available for box, polygon, + circle. + + box '(1,1),(0,0)' &< box '(2,2),(0,0)' + t + + + + + + geometric_type &> geometric_type + boolean + + Does first object not extend to the left of second? + Available for box, polygon, + circle. + + box '(3,3),(0,0)' &> box '(2,2),(0,0)' + t + + + + + + geometric_type <<| geometric_type + boolean + + Is first object strictly below second? + Available for box, polygon, + circle. + + box '(3,3),(0,0)' <<| box '(5,5),(3,4)' + t + + + + + + geometric_type |>> geometric_type + boolean + + Is first object strictly above second? + Available for box, polygon, + circle. + + box '(5,5),(3,4)' |>> box '(3,3),(0,0)' + t + + + + + + geometric_type &<| geometric_type + boolean + + Does first object not extend above second? + Available for box, polygon, + circle. + + box '(1,1),(0,0)' &<| box '(2,2),(0,0)' + t + + + + + + geometric_type |&> geometric_type + boolean + + Does first object not extend below second? + Available for box, polygon, + circle. + + box '(3,3),(0,0)' |&> box '(2,2),(0,0)' + t + + + + + + box <^ box + boolean + + Is first object below second (allows edges to touch)? + + box '((1,1),(0,0))' <^ box '((2,2),(1,1))' + t + + + + + + point <^ point + boolean + + Is first object strictly below second? + (This operator is misnamed; it should be <<|.) + + point '(1,0)' <^ point '(1,1)' + t + + + + + + box >^ box + boolean + + Is first object above second (allows edges to touch)? + + box '((2,2),(1,1))' >^ box '((1,1),(0,0))' + t + + + + + + point >^ point + boolean + + Is first object strictly above second? + (This operator is misnamed; it should be |>>.) + + point '(1,1)' >^ point '(1,0)' + t + + + + + + geometric_type ?# geometric_type + boolean + + Do these objects intersect? + Available for these pairs of types: + (box, box), + (lseg, box), + (lseg, lseg), + (lseg, line), + (line, box), + (line, line), + (path, path). + + lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)' + t + + + + + + ?- geometric_type + boolean + + Is line horizontal? + Available for lseg, line. + + ?- lseg '[(-1,0),(1,0)]' + t + + + + + + point ?- point + boolean + + Are points horizontally aligned (that is, have same y coordinate)? + + point '(1,0)' ?- point '(0,0)' + t + + + + + + ?| geometric_type + boolean + + Is line vertical? + Available for lseg, line. + + ?| lseg '[(-1,0),(1,0)]' + f + + + + + + point ?| point + boolean + + Are points vertically aligned (that is, have same x coordinate)? + + point '(0,1)' ?| point '(0,0)' + t + + + + + + geometric_type ?-| geometric_type + boolean + + Are lines perpendicular? + Available for lseg, line. + + lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' + t + + + + + + geometric_type ?|| geometric_type + boolean + + Are lines parallel? + Available for lseg, line. + + lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' + t + + + + + + geometric_type ~= geometric_type + boolean + + Are these objects the same? + Available for point, box, + polygon, circle. + + polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))' + t + + + + +
+ - Note that the same as operator, ~=, represents - the usual notion of equality for the point, + Note that the same as operator, ~=, + represents the usual notion of equality for the point, box, polygon, and circle types. - Some of these types also have an = operator, but - = compares - for equal areas only. The other scalar comparison operators - (<= and so on) likewise compare areas for these types. + Some of the geometric types also have an = operator, but + = compares for equal areas only. + The other scalar comparison operators (<= and so + on), where available for these types, likewise compare areas. - - Geometric Operators - - - - Operator - Description - Example - - - - - + - Translation - box '((0,0),(1,1))' + point '(2.0,0)' - - - - - Translation - box '((0,0),(1,1))' - point '(2.0,0)' - - - * - Scaling/rotation - box '((0,0),(1,1))' * point '(2.0,0)' - - - / - Scaling/rotation - box '((0,0),(2,2))' / point '(2.0,0)' - - - # - Point or box of intersection - box '((1,-1),(-1,1))' # box '((1,1),(-2,-2))' - - - # - Number of points in path or polygon - # path '((1,0),(0,1),(-1,0))' - - - @-@ - Length or circumference - @-@ path '((0,0),(1,0))' - - - @@ - Center - @@ circle '((0,0),10)' - - - ## - Closest point to first operand on second operand - point '(0,0)' ## lseg '((2,0),(0,2))' - - - <-> - Distance between - circle '((0,0),1)' <-> circle '((5,0),1)' - - - && - Overlaps? (One point in common makes this true.) - box '((0,0),(1,1))' && box '((0,0),(2,2))' - - - << - Is strictly left of? - circle '((0,0),1)' << circle '((5,0),1)' - - - >> - Is strictly right of? - circle '((5,0),1)' >> circle '((0,0),1)' - - - &< - Does not extend to the right of? - box '((0,0),(1,1))' &< box '((0,0),(2,2))' - - - &> - Does not extend to the left of? - box '((0,0),(3,3))' &> box '((0,0),(2,2))' - - - <<| - Is strictly below? - box '((0,0),(3,3))' <<| box '((3,4),(5,5))' - - - |>> - Is strictly above? - box '((3,4),(5,5))' |>> box '((0,0),(3,3))' - - - &<| - Does not extend above? - box '((0,0),(1,1))' &<| box '((0,0),(2,2))' - - - |&> - Does not extend below? - box '((0,0),(3,3))' |&> box '((0,0),(2,2))' - - - <^ - Is below (allows touching)? - circle '((0,0),1)' <^ circle '((0,5),1)' - - - >^ - Is above (allows touching)? - circle '((0,5),1)' >^ circle '((0,0),1)' - - - ?# - Intersects? - lseg '((-1,0),(1,0))' ?# box '((-2,-2),(2,2))' - - - ?- - Is horizontal? - ?- lseg '((-1,0),(1,0))' - - - ?- - Are horizontally aligned? - point '(1,0)' ?- point '(0,0)' - - - ?| - Is vertical? - ?| lseg '((-1,0),(1,0))' - - - ?| - Are vertically aligned? - point '(0,1)' ?| point '(0,0)' - - - ?-| - Is perpendicular? - lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))' - - - ?|| - Are parallel? - lseg '((-1,0),(1,0))' ?|| lseg '((-1,2),(1,2))' - - - @> - Contains? - circle '((0,0),2)' @> point '(1,1)' - - - <@ - Contained in or on? - point '(1,1)' <@ circle '((0,0),2)' - - - ~= - Same as? - polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))' - - - -
- Before PostgreSQL 8.2, the containment @@ -9637,308 +10025,532 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple - - area - - - center - - - diameter - - - height - - - isclosed - - - isopen - - - length - - - npoints - - - pclose - - - popen - - - radius - - - width - - - Geometric Functions - - - - Function - Return Type - Description - Example - - - - - area(object) - double precision - area - area(box '((0,0),(1,1))') - - - center(object) - point - center - center(box '((0,0),(1,2))') - - - diameter(circle) - double precision - diameter of circle - diameter(circle '((0,0),2.0)') - - - height(box) - double precision - vertical size of box - height(box '((0,0),(1,1))') - - - isclosed(path) - boolean - a closed path? - isclosed(path '((0,0),(1,1),(2,0))') - - - isopen(path) - boolean - an open path? - isopen(path '[(0,0),(1,1),(2,0)]') - - - length(object) - double precision - length - length(path '((-1,0),(1,0))') - - - npoints(path) - int - number of points - npoints(path '[(0,0),(1,1),(2,0)]') - - - npoints(polygon) - int - number of points - npoints(polygon '((1,1),(0,0))') - - - pclose(path) - path - convert path to closed - pclose(path '[(0,0),(1,1),(2,0)]') - - - popen(path) - path - convert path to open - popen(path '((0,0),(1,1),(2,0))') - - - radius(circle) - double precision - radius of circle - radius(circle '((0,0),2.0)') - - - width(box) - double precision - horizontal size of box - width(box '((0,0),(1,1))') - - - + Geometric Functions + + + + + FunctionDescriptionExample(s) + + + + + + + + + area + + area ( geometric_type ) + double precision + + Computes area. + Available for box, path, circle. + A path input must be closed, else NULL is returned. + Also, if the path is self-intersecting, the result may be + meaningless. + + area(box '(2,2),(0,0)') + 4 + + + + + + + center + + center ( geometric_type ) + point + + Computes center point. + Available for box, circle. + + center(box '(1,2),(0,0)') + (0.5,1) + + + + + + + diagonal + + diagonal ( box ) + lseg + + Extracts box's diagonal as a line segment + (same as lseg(box)). + + diagonal(box '(1,2),(0,0)') + [(1,2),(0,0)] + + + + + + + diameter + + diameter ( circle ) + double precision + + Computes diameter of circle. + + diameter(circle '<(0,0),2>') + 4 + + + + + + + height + + height ( box ) + double precision + + Computes vertical size of box. + + height(box '(1,2),(0,0)') + 2 + + + + + + + isclosed + + isclosed ( path ) + boolean + + Is path closed? + + isclosed(path '((0,0),(1,1),(2,0))') + t + + + + + + + isopen + + isopen ( path ) + boolean + + Is path open? + + isopen(path '[(0,0),(1,1),(2,0)]') + t + + + + + + + length + + length ( geometric_type ) + double precision + + Computes the total length. + Available for lseg, path. + + length(path '((-1,0),(1,0))') + 4 + + + + + + + npoints + + npoints ( geometric_type ) + integer + + Returns the number of points. + Available for path, polygon. + + npoints(path '[(0,0),(1,1),(2,0)]') + 3 + + + + + + + pclose + + pclose ( path ) + path + + Converts path to closed form. + + pclose(path '[(0,0),(1,1),(2,0)]') + ((0,0),(1,1),(2,0)) + + + + + + + popen + + popen ( path ) + path + + Converts path to open form. + + popen(path '((0,0),(1,1),(2,0))') + [(0,0),(1,1),(2,0)] + + + + + + + radius + + radius ( circle ) + double precision + + Computes radius of circle. + + radius(circle '<(0,0),2>') + 2 + + + + + + + slope + + slope ( point, point ) + double precision + + Computes slope of a line drawn through the two points. + + slope(point '(0,0)', point '(2,1)') + 0.5 + + + + + + + width + + width ( box ) + double precision + + Computes horizontal size of box. + + width(box '(1,2),(0,0)') + 1 + + + +
- Geometric Type Conversion Functions - - - - Function - Return Type - Description - Example - - - - - - - box - - box(circle) - - box - circle to box - box(circle '((0,0),2.0)') - - - box(point) - box - point to empty box - box(point '(0,0)') - - - box(point, point) - box - points to box - box(point '(0,0)', point '(1,1)') - - - box(polygon) - box - polygon to box - box(polygon '((0,0),(1,1),(2,0))') - - - bound_box(box, box) - box - boxes to bounding box - bound_box(box '((0,0),(1,1))', box '((3,3),(4,4))') - - - - - circle - - circle(box) - - circle - box to circle - circle(box '((0,0),(1,1))') - - - circle(point, double precision) - circle - center and radius to circle - circle(point '(0,0)', 2.0) - - - circle(polygon) - circle - polygon to circle - circle(polygon '((0,0),(1,1),(2,0))') - - - line(point, point) - line - points to line - line(point '(-1,0)', point '(1,0)') - - - - - lseg - - lseg(box) - - lseg - box diagonal to line segment - lseg(box '((-1,0),(1,0))') - - - lseg(point, point) - lseg - points to line segment - lseg(point '(-1,0)', point '(1,0)') - - - - - path - - path(polygon) - - path - polygon to path - path(polygon '((0,0),(1,1),(2,0))') - - - - - point - - point(double - precision, double precision) - - point - construct point - point(23.4, -44.5) - - - point(box) - point - center of box - point(box '((-1,0),(1,0))') - - - point(circle) - point - center of circle - point(circle '((0,0),2.0)') - - - point(lseg) - point - center of line segment - point(lseg '((-1,0),(1,0))') - - - point(polygon) - point - center of polygon - point(polygon '((0,0),(1,1),(2,0))') - - - - - polygon - - polygon(box) - - polygon - box to 4-point polygon - polygon(box '((0,0),(1,1))') - - - polygon(circle) - polygon - circle to 12-point polygon - polygon(circle '((0,0),2.0)') - - - polygon(npts, circle) - polygon - circle to npts-point polygon - polygon(12, circle '((0,0),2.0)') - - - polygon(path) - polygon - path to polygon - polygon(path '((0,0),(1,1),(2,0))') - - - + Geometric Type Conversion Functions + + + + + FunctionDescriptionExample(s) + + + + + + + + + box + + box ( circle ) + box + + Computes box inscribed within the circle. + + box(circle '<(0,0),2>') + (1.414213562373095,1.414213562373095),&zwsp;(-1.414213562373095,-1.414213562373095) + + + + + + box ( point ) + box + + Converts point to empty box. + + box(point '(1,0)') + (1,0),(1,0) + + + + + + box ( point, point ) + box + + Converts any two corner points to box. + + box(point '(0,1)', point '(1,0)') + (1,1),(0,0) + + + + + + box ( polygon ) + box + + Computes bounding box of polygon. + + box(polygon '((0,0),(1,1),(2,0))') + (2,1),(0,0) + + + + + + + bound_box + + bound_box ( box, box ) + box + + Computes bounding box of two boxes. + + bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') + (4,4),(0,0) + + + + + + + circle + + circle ( box ) + circle + + Computes smallest circle enclosing box. + + circle(box '(1,1),(0,0)') + <(0.5,0.5),0.7071067811865476> + + + + + + circle ( point, double precision ) + circle + + Constructs circle from center and radius. + + circle(point '(0,0)', 2.0) + <(0,0),2> + + + + + + circle ( polygon ) + circle + + Converts polygon to circle. The circle's center is the mean of the + positions of the polygon's points, and the radius is the average + distance of the polygon's points from that center. + + circle(polygon '((0,0),(1,3),(2,0))') + <(1,1),1.6094757082487299> + + + + + + + line + + line ( point, point ) + line + + Converts two points to the line through them. + + line(point '(-1,0)', point '(1,0)') + {0,-1,0} + + + + + + + lseg + + lseg ( box ) + lseg + + Extracts box's diagonal as a line segment. + + lseg(box '(1,0),(-1,0)') + [(1,0),(-1,0)] + + + + + + lseg ( point, point ) + lseg + + Constructs line segment from two endpoints. + + lseg(point '(-1,0)', point '(1,0)') + [(-1,0),(1,0)] + + + + + + + path + + path ( polygon ) + path + + Converts polygon to a closed path with the same list of points. + + path(polygon '((0,0),(1,1),(2,0))') + ((0,0),(1,1),(2,0)) + + + + + + + point + + point ( double precision, double precision ) + point + + Constructs point from its coordinates. + + point(23.4, -44.5) + (23.4,-44.5) + + + + + + point ( box ) + point + + Computes center of box. + + point(box '(1,0),(-1,0)') + (0,0) + + + + + + point ( circle ) + point + + Computes center of circle. + + point(circle '<(0,0),2>') + (0,0) + + + + + + point ( lseg ) + point + + Computes center of line segment. + + point(lseg '[(-1,0),(1,0)]') + (0,0) + + + + + + point ( polygon ) + point + + Computes center of polygon (the mean of the + positions of the polygon's points). + + point(polygon '((0,0),(1,1),(2,0))') + (1,0.3333333333333333) + + + + + + + polygon + + polygon ( box ) + polygon + + Converts box to a 4-point polygon. + + polygon(box '(1,1),(0,0)') + ((0,0),(0,1),(1,1),(1,0)) + + + + + + polygon ( circle ) + polygon + + Converts circle to a 12-point polygon. + + polygon(circle '<(0,0),2>') + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) + + + + + + polygon ( integer, circle ) + polygon + + Converts circle to an n-point polygon. + + polygon(4, circle '<(3,0),1>') + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) + + + + + + polygon ( path ) + polygon + + Converts closed path to a polygon with the same list of points. + + polygon(path '((0,0),(1,1),(2,0))') + ((0,0),(1,1),(2,0)) + + + + +
@@ -9951,22 +10563,6 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple as an array of two point values. - - The area function works for the types - box, circle, and path. - The area function only works on the - path data type if the points in the - path are non-intersecting. For example, the - path - '((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))'::PATH - will not work; however, the following visually identical - path - '((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH - will work. If the concept of an intersecting versus - non-intersecting path is confusing, draw both of the - above paths side by side on a piece of graph paper. - -