====================== 几何函数和操作符 ====================== .. container:: sect1 :name: FUNCTIONS-GEOMETRY .. container:: titlepage .. container:: .. container:: .. rubric:: 9.11. 几何函数和操作符 :name: 几何函数和操作符 :class: title 几何类型\ ``point``\ 、\ ``box``\ 、 ``lseg``\ 、\ ``line``\ 、\ ``path``\ 、 ``polygon``\ 和\ ``circle``\ 有一大堆本地支持函数和操作符,如\ `表 9.34 `__\ 、\ `表 9.35 `__\ 和\ `表 9.36 `__\ 中所示。 .. caution:: .. rubric:: 小心 :name: 小心 :class: title 请注意“same as”操作符(\ ``~=``\ ),表示\ ``point``\ 、\ ``box``\ 、\ ``polygon``\ 和\ ``circle``\ 类型的一般相等概念。这些类型中的某些还有一个\ ``=``\ 操作符,但是\ ``=``\ 只比较相同的\ *面积*\ 。其它的标量比较操作符 (\ ``<=``\ 等等)也是为这些类型比较面积。 .. container:: table :name: FUNCTIONS-GEOMETRY-OP-TABLE **表 9.34. 几何操作符** .. container:: table-contents +---------+----------------------------+----------------------------+ | 操作符 | 描述 | 例子 | +=========+============================+============================+ | ``+`` | 平移 | ``box '((0,0),( | | | | 1,1))' + point '(2.0,0)'`` | +---------+----------------------------+----------------------------+ | ``-`` | 平移 | ``box '((0,0),( | | | | 1,1))' - point '(2.0,0)'`` | +---------+----------------------------+----------------------------+ | ``*`` | 缩放/旋转 | ``box '((0,0),( | | | | 1,1))' * point '(2.0,0)'`` | +---------+----------------------------+----------------------------+ | ``/`` | 缩放/旋转 | ``box '((0,0),( | | | | 2,2))' / point '(2.0,0)'`` | +---------+----------------------------+----------------------------+ | ``#`` | 相交的点或方框 | ``box '((1,-1),(-1,1))' | | | | # box '((1,1),(-2,-2))'`` | +---------+----------------------------+----------------------------+ | ``#`` | 路径或多边形中的点数 | ``# pat | | | | h '((1,0),(0,1),(-1,0))'`` | +---------+----------------------------+----------------------------+ | ``@-@`` | 长度或周长 | `` | | | | @-@ path '((0,0),(1,0))'`` | +---------+----------------------------+----------------------------+ | ``@@`` | 中心 | ``@@ circle '((0,0),10)'`` | +---------+----------------------------+----------------------------+ | ``##`` | 第二个操作 | ``point '(0,0)' | | | 数上最接近第一个操作数的点 | ## lseg '((2,0),(0,2))'`` | +---------+----------------------------+----------------------------+ | ``<->`` | 距离 | ``circle '((0,0),1) | | | | ' <-> circle '((5,0),1)'`` | +---------+----------------------------+----------------------------+ | ``&&`` | 是否重叠?( | ``box '((0,0),(1,1)) | | | 只要有一个公共点这就为真) | ' && box '((0,0),(2,2))'`` | +---------+----------------------------+----------------------------+ | ``<<`` | 是否严格地在左侧? | ``circle '((0,0),1 | | | | )' << circle '((5,0),1)'`` | +---------+----------------------------+----------------------------+ | ``>>`` | 是否严格地在右侧? | ``circle '((5,0),1 | | | | )' >> circle '((0,0),1)'`` | +---------+----------------------------+----------------------------+ | ``&<`` | 没有延展到右边? | ``box '((0,0),(1,1)) | | | | ' &< box '((0,0),(2,2))'`` | +---------+----------------------------+----------------------------+ | ``&>`` | 没有延展到左边? | ``box '((0,0),(3,3)) | | | | ' &> box '((0,0),(2,2))'`` | +---------+----------------------------+----------------------------+ | ``<<|`` | 严格在下? | ``box '((0,0),(3,3))' | | | | <<| box '((3,4),(5,5))'`` | +---------+----------------------------+----------------------------+ | ``|>>`` | 严格在上? | ``box '((3,4),(5,5))' | | | | |>> box '((0,0),(3,3))'`` | +---------+----------------------------+----------------------------+ | ``&<|`` | 没有延展到上面? | ``box '((0,0),(1,1))' | | | | &<| box '((0,0),(2,2))'`` | +---------+----------------------------+----------------------------+ | ``|&>`` | 没有延展到下面? | ``box '((0,0),(3,3))' | | | | |&> box '((0,0),(2,2))'`` | +---------+----------------------------+----------------------------+ | ``<^`` | 在下面(允许相切)? | ``circle '((0,0),1 | | | | )' <^ circle '((0,5),1)'`` | +---------+----------------------------+----------------------------+ | ``>^`` | 在上面(允许相切)? | ``circle '((0,5),1 | | | | )' >^ circle '((0,0),1)'`` | +---------+----------------------------+----------------------------+ | ``?#`` | 相交? | ``lseg '((-1,0),(1,0))' | | | | ?# box '((-2,-2),(2,2))'`` | +---------+----------------------------+----------------------------+ | ``?-`` | 水平? | `` | | | | ?- lseg '((-1,0),(1,0))'`` | +---------+----------------------------+----------------------------+ | ``?-`` | 水平对齐? | ``point | | | | '(1,0)' ?- point '(0,0)'`` | +---------+----------------------------+----------------------------+ | ``?|`` | 垂直? | `` | | | | ?| lseg '((-1,0),(1,0))'`` | +---------+----------------------------+----------------------------+ | ``?|`` | 垂直对齐? | ``point | | | | '(0,1)' ?| point '(0,0)'`` | +---------+----------------------------+----------------------------+ | ``?-|`` | 相互垂直? | ``lseg '((0,0),(0,1))' | | | | ?-| lseg '((0,0),(1,0))'`` | +---------+----------------------------+----------------------------+ | ``?||`` | 平行? | ``lseg '((-1,0),(1,0))' ? | | | | || lseg '((-1,2),(1,2))'`` | +---------+----------------------------+----------------------------+ | ``@>`` | 包含? | ``circle '((0 | | | | ,0),2)' @> point '(1,1)'`` | +---------+----------------------------+----------------------------+ | ``<@`` | 包含在内或在上? | ``point '(1,1 | | | | )' <@ circle '((0,0),2)'`` | +---------+----------------------------+----------------------------+ | ``~=`` | 相同? | `` | | | | polygon '((0,0),(1,1))' ~= | | | | polygon '((1,1),(0,0))'`` | +---------+----------------------------+----------------------------+ .. note:: .. rubric:: 注意 :name: 注意 :class: title 在PostgreSQL之前,包含操作符\ ``@>``\ 和\ ``<@``\ 被分别称为\ ``~``\ 和\ ``@``\ 。 这些名字仍然可以使用,但是已被废除并且最终将被移除。 .. container:: table :name: FUNCTIONS-GEOMETRY-FUNC-TABLE **表 9.35. 几何函数** .. container:: table-contents +----------------+----------------+----------------+----------------+ | 函数 | 返回类型 | 描述 | 例子 | +================+================+================+================+ | `` | ``doub | 面积 | ` | | area(object``) | le precision`` | | `area(box '((0 | | | | | ,0),(1,1))')`` | +----------------+----------------+----------------+----------------+ | ``ce | ``point`` | 中心 | ``c | | nter(object``) | | | enter(box '((0 | | | | | ,0),(1,2))')`` | +----------------+----------------+----------------+----------------+ | ``diam | ``doub | 圆的直径 | ``diam | | eter(circle``) | le precision`` | | eter(circle '( | | | | | (0,0),2.0)')`` | +----------------+----------------+----------------+----------------+ | ` | ``doub | 方框的垂直尺寸 | ``h | | `height(box``) | le precision`` | | eight(box '((0 | | | | | ,0),(1,1))')`` | +----------------+----------------+----------------+----------------+ | ``is | ``boolean`` | 一个封闭路径? | ``isclosed(p | | closed(path``) | | | ath '((0,0),(1 | | | | | ,1),(2,0))')`` | +----------------+----------------+----------------+----------------+ | `` | ``boolean`` | 一个开放路径? | ``isopen(p | | isopen(path``) | | | ath '[(0,0),(1 | | | | | ,1),(2,0)]')`` | +----------------+----------------+----------------+----------------+ | ``le | ``doub | 长度 | ``len | | ngth(object``) | le precision`` | | gth(path '((-1 | | | | | ,0),(1,0))')`` | +----------------+----------------+----------------+----------------+ | ``n | ``int`` | 点数 | ``npoints(p | | points(path``) | | | ath '[(0,0),(1 | | | | | ,1),(2,0)]')`` | +----------------+----------------+----------------+----------------+ | ``npoi | ``int`` | 点数 | ``npoint | | nts(polygon``) | | | s(polygon '((1 | | | | | ,1),(0,0))')`` | +----------------+----------------+----------------+----------------+ | `` | ``path`` | 将路 | ``pclose(p | | pclose(path``) | | 径转换成封闭的 | ath '[(0,0),(1 | | | | | ,1),(2,0)]')`` | +----------------+----------------+----------------+----------------+ | ` | ``path`` | 将 | ``popen(p | | `popen(path``) | | 路径转换成开放 | ath '((0,0),(1 | | | | | ,1),(2,0))')`` | +----------------+----------------+----------------+----------------+ | ``ra | ``doub | 圆的半径 | ``ra | | dius(circle``) | le precision`` | | dius(circle '( | | | | | (0,0),2.0)')`` | +----------------+----------------+----------------+----------------+ | ``width(box``) | ``doub | 方框的水平尺寸 | `` | | | le precision`` | | width(box '((0 | | | | | ,0),(1,1))')`` | +----------------+----------------+----------------+----------------+ .. container:: table :name: FUNCTIONS-GEOMETRY-CONV-TABLE **表 9.36. 几何类型转换函数** .. container:: table-contents +-----------------+-------------+-----------------+-----------------+ | 函数 | 返回类型 | 描述 | 例子 | +=================+=============+=================+=================+ | | ``box`` | 圆到方框 | ``box(circle ' | | ``box(circle``) | | | ((0,0),2.0)')`` | +-----------------+-------------+-----------------+-----------------+ | ``box(point``) | ``box`` | 点到空方框 | ``box(p | | | | | oint '(0,0)')`` | +-----------------+-------------+-----------------+-----------------+ | ``box(point``, | ``box`` | 点到方框 | ``box(p | | ``point``) | | | oint '(0,0)', p | | | | | oint '(1,1)')`` | +-----------------+-------------+-----------------+-----------------+ | ` | ``box`` | 多边形到方框 | ``box(po | | `box(polygon``) | | | lygon '((0,0),( | | | | | 1,1),(2,0))')`` | +-----------------+-------------+-----------------+-----------------+ | ``b | ``box`` | 方框到外包框 | ``bound_bo | | ound_box(box``, | | | x(box '((0,0),( | | ``box``) | | | 1,1))', box '(( | | | | | 3,3),(4,4))')`` | +-----------------+-------------+-----------------+-----------------+ | | ``circle`` | 方框到圆 | ` | | ``circle(box``) | | | `circle(box '(( | | | | | 0,0),(1,1))')`` | +-----------------+-------------+-----------------+-----------------+ | `` | ``circle`` | 中心和半径到圆 | ``circle(point | | circle(point``, | | | '(0,0)', 2.0)`` | | ``doub | | | | | le precision``) | | | | +-----------------+-------------+-----------------+-----------------+ | ``ci | ``circle`` | 多边形到圆 | ``circle(po | | rcle(polygon``) | | | lygon '((0,0),( | | | | | 1,1),(2,0))')`` | +-----------------+-------------+-----------------+-----------------+ | ``line(point``, | ``line`` | 点到线 | ``line(po | | ``point``) | | | int '(-1,0)', p | | | | | oint '(1,0)')`` | +-----------------+-------------+-----------------+-----------------+ | ``lseg(box``) | ``lseg`` | 方 | ``lseg(box '((- | | | | 框对角线到线段 | 1,0),(1,0))')`` | +-----------------+-------------+-----------------+-----------------+ | ``lseg(point``, | ``lseg`` | 点到线段 | ``lseg(po | | ``point``) | | | int '(-1,0)', p | | | | | oint '(1,0)')`` | +-----------------+-------------+-----------------+-----------------+ | | ``path`` | 多边形到路径 | ``path(po | | `` | | | lygon '((0,0),( | | path(polygon``) | | | 1,1),(2,0))')`` | +-----------------+-------------+-----------------+-----------------+ | | ``point`` | 构造点 | ``point | | ``point``\ ( | | | (23.4, -44.5)`` | | ``double | | | | | precision``, | | | | | ``doub | | | | | le precision``) | | | | +-----------------+-------------+-----------------+-----------------+ | ``point(box``) | ``point`` | 方框的中心 | ` | | | | | `point(box '((- | | | | | 1,0),(1,0))')`` | +-----------------+-------------+-----------------+-----------------+ | `` | ``point`` | 圆的中心 | ` | | point(circle``) | | | `point(circle ' | | | | | ((0,0),2.0)')`` | +-----------------+-------------+-----------------+-----------------+ | ``point(lseg``) | ``point`` | 线段的中心 | `` | | | | | point(lseg '((- | | | | | 1,0),(1,0))')`` | +-----------------+-------------+-----------------+-----------------+ | ``p | ``point`` | 多边形的中心 | ``point(po | | oint(polygon``) | | | lygon '((0,0),( | | | | | 1,1),(2,0))')`` | +-----------------+-------------+-----------------+-----------------+ | | ``polygon`` | 方框到4点多边形 | `` | | ` | | | polygon(box '(( | | `polygon(box``) | | | 0,0),(1,1))')`` | +-----------------+-------------+-----------------+-----------------+ | ``po | ``polygon`` | 圆到12点多边形 | ``p | | lygon(circle``) | | | olygon(circle ' | | | | | ((0,0),2.0)')`` | +-----------------+-------------+-----------------+-----------------+ | `` | ``polygon`` | 点到\ *``np | ``polyg | | polygon(npts``, | | ts``*\ 点多边形 | on(12, circle ' | | ``circle``) | | | ((0,0),2.0)')`` | +-----------------+-------------+-----------------+-----------------+ | `` | ``polygon`` | 路径到多边形 | ``polygon | | polygon(path``) | | | (path '((0,0),( | | | | | 1,1),(2,0))')`` | +-----------------+-------------+-----------------+-----------------+ 我们可以把一个\ ``point``\ 的两个组成数字当作具有索引 0 和 1 的数组访问。例如,如果\ ``t.p``\ 是一个\ ``point``\ 列,那么\ ``SELECT p[0] FROM t``\ 检索 X 座标而 ``UPDATE t SET p[1] = ...``\ 改变 Y 座标。同样,\ ``box``\ 或者\ ``lseg``\ 类型的值可以当作两个\ ``point``\ 值的数组值看待。 函数\ ``area``\ 可以用于类型\ ``box``\ 、\ ``circle``\ 和\ ``path``\ 。\ ``area``\ 函数操作\ ``path``\ 数据类型的时候, 只有在\ ``path``\ 的点没有交叉的情况下才可用。例如,\ ``path`` ``'((0,0),(0,1),(2,1),(2,2),(1,2),(1,0),(0,0))'::PATH``\ 是不行的, 而下面的视觉上相同的 ``path`` ``'((0,0),(0,1),(1,1),(1,2),(2,2),(2,1),(1,1),(1,0),(0,0))'::PATH``\ 就可以。 如果交叉和不交叉的\ ``path``\ 概念让你疑惑,那么把上面两个\ ``path``\ 都画在一张图纸上,你就明白了。