Геометрические функции и операторы

Для геометрических типов point (точка), box (прямоугольник), lseg (отрезок), line (прямая), path (путь), polygon (многоугольник) и circle (окружность) существует большой набор встроенных вспомогательных функций и операторов, приведенных в Таблице 35, Таблице 36 и Таблице 37.

Таблица 35. Геометрические операторы

Оператор
Описание
Пример(ы)
геометрический_тип + point → геометрический_тип
Добавляет координаты второго аргумента типа point к координатам каждой точки первого аргумента, тем самым осуществляя перенос объекта. Имеется для типов point, box, path, circle.
box '(1,1),(0,0)' + point '(2,0)' → (3,1),(2,0)
path + path → path
Конкатенирует два открытых пути (возвращает NULL, если один из путей замкнут).
path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' → [(0,0),(1,1),(2,2),(3,3),(4,4)]
геометрический_тип - point → геометрический_тип
Вычитает координаты второго аргумента типа point из координат каждой точки первого аргумента, тем самым осуществляя перенос объекта. Имеется для типов point, box, path, circle.
box '(1,1),(0,0)' - point '(2,0)' → (-1,1),(-2,0)
геометрический_тип * point → геометрический_тип
Умножает каждую точку первого аргумента на второй аргумент типа point (воспринимая точки как комплексные числа, представленные действительной и мнимой частями, и проводя стандартное комплексное умножение). Если интерпретировать второй аргумент типа point как вектор, это будет равнозначно увеличению размера этого объекта и расстояния от начала координат при помощи длины этого вектора с поворотом объекта против часовой стрелки относительно начала координат на угол, равный углу между вектором и осью x. Имеется для типов point, box,[a] 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),​(0.7071067811865475,0.7071067811865475),​(0,1.414213562373095))
геометрический_тип / point → геометрический_тип
Делит каждую точку первого аргумента на второй аргумент типа point (воспринимая точки как комплексные числа, представленные действительной и мнимой частями, и проводя стандартное комплексное деление). Если интерпретировать второй аргумент типа point как вектор, это будет равнозначно уменьшению размера этого объекта и расстояния от начала координат при помощи длины этого вектора с поворотом объекта по часовой стрелки относительно начала координат на угол, равный углу между вектором и осью x. Имеется для типов point, box,[a] 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),​(0.7071067811865476,-0.7071067811865476),​(1.4142135623730951,0))
@-@ геометрический_тип → double precision
Вычисляет общую длину. Имеется для типов lseg, path.
@-@ path '[(0,0),(1,0),(1,1)]' → 2
@@ геометрический_тип → point
Вычисляет центральную точку. Имеется для типов box, lseg, polygon, circle.
@@ box '(2,2),(0,0)' → (1,1)
box # box → box
Вычисляет пересечение двух прямоугольников или возвращает NULL, если такого пересечения нет.
box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' → (1,1),(-1,-1)
геометрический_тип ## геометрический_тип → point
Вычисляет ближайшую к первому объекту точку на втором объекте. Имеется для этих пар типов: (point, box), (point, lseg), (point, line), (lseg, box), (lseg, lseg), (line, lseg).
point '(0,0)' ## lseg '[(2,0),(0,2)]' → (1,1)
геометрический_тип <-> геометрический_тип → double precision
Вычисляет расстояние между объектами. Имеется для всех геометрических типов, кроме polygon, для всех сочетаний типа point с другим геометрическим типом, а также для этих пар типов: (box, lseg), (lseg, line), (polygon, circle) (и для этих пар в обратном порядке).
circle '<(0,0),1>' <-> circle '<(5,0),1>' → 3
геометрический_тип @> геометрический_тип → boolean
Первый объект содержит второй? Имеется для этих пар типов: (box, point), (box, box), (path, point), (polygon, point), (polygon, polygon), (circle, point), (circle, circle).
circle '<(0,0),2>' @> point '(1,1)' → t
геометрический_тип <@ геометрический_тип → boolean
Первый объект содержится в (находится на) втором? Имеется для этих пар типов: (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
геометрический_тип && геометрический_тип → boolean
Эти объекты пересекаются? (Для результата true достаточно одной общей точки.) Имеется для типов box, polygon, circle.
box '(1,1),(0,0)' && box '(2,2),(0,0)' → t
геометрический_тип << геометрический_тип → boolean
Первый объект строго слева от второго? Имеется для типов point, box, polygon, circle.
circle '<(0,0),1>' << circle '<(5,0),1>' → t
геометрический_тип >> геометрический_тип → boolean
Первый объект строго справа от второго? Имеется для типов point, box, polygon, circle.
circle '<(5,0),1>' >> circle '<(0,0),1>' → t
геометрический_тип &< геометрический_тип → boolean
Первый объект не простирается правее второго? Имеется для типов box, polygon, circle.
box '(1,1),(0,0)' &< box '(2,2),(0,0)' → t
геометрический_тип &> геометрический_тип → boolean
Первый объект не простирается левее второго? Имеется для типов box, polygon, circle.
box '(3,3),(0,0)' &> box '(2,2),(0,0)' → t
геометрический_тип <<| геометрический_тип → boolean
Первый объект строго ниже второго? Имеется для типов point, box, polygon, circle.
box '(3,3),(0,0)' <<| box '(5,5),(3,4)' → t
геометрический_тип |>> геометрический_тип → boolean
Первый объект строго выше второго? Имеется для типов point, box, polygon, circle.
box '(5,5),(3,4)' |>> box '(3,3),(0,0)' → t
геометрический_тип &<| геометрический_тип → boolean
Первый объект не простирается выше второго? Имеется для типов box, polygon, circle.
box '(1,1),(0,0)' &<| box '(2,2),(0,0)' → t
геометрический_тип |&> геометрический_тип → boolean
Первый объект не простирается ниже второго? Имеется для типов box, polygon, circle.
box '(3,3),(0,0)' |&> box '(2,2),(0,0)' → t
box <^ box → boolean
Первый объект ниже второго (объекты могут соприкасаться краями)?
box '((1,1),(0,0))' <^ box '((2,2),(1,1))' → t
box >^ box → boolean
Первый объект выше второго (объекты могут соприкасаться краями)?
box '((2,2),(1,1))' >^ box '((1,1),(0,0))' → t
геометрический_тип ?# геометрический_тип → boolean
Эти объекты пересекаются? Имеется для этих пар типов: (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
?- line → boolean
?- lseg → boolean
Линия горизонтальна?
?- lseg '[(-1,0),(1,0)]' → t
point ?- point → boolean
Точки выровнены по горизонтали (то есть имеют одинаковую координату по y)?
point '(1,0)' ?- point '(0,0)' → t
?| line → boolean
?| lseg → boolean
Линия вертикальна?
?| lseg '[(-1,0),(1,0)]' → f
point ?| point → boolean
Точки выровнены по вертикали (то есть имеют одинаковую координату по x)?
point '(0,1)' ?| point '(0,0)' → t
line ?-| line → boolean
lseg ?-| lseg → boolean
Линии перпендикулярны?
lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' → t
line ?|| line → boolean
lseg ?|| lseg → boolean
Линии параллельны?
lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' → t
геометрический_тип ~= геометрический_тип → boolean
Эти объекты совпадают? Имеется для типов point, box, polygon, circle.
polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))' → t
[a] При «повороте» прямоугольника с помощью этих операторов перемещаются только его угловые точки: стороны этого прямоугольника по-прежнему считаются параллельными осям. Как следствие, в отличие от истинного поворота, при этой операции размер прямоугольника меняется.

ВНИМАНИЕ!
Обратите внимание, что оператор «тождественности», ~=, представляет собой обычную проверку равенства для типов point, box, polygon и circle. Для некоторых геометрических типов также имеется оператор =, но = проверяет только равенство площадей. Другие скалярные операторы сравнения (<= и т. п.) для тех типов, для которых они имеются, также сравнивают площади.

Таблица 36. Геометрические функции

Функция
Описание
Пример(ы)
area ( геометрический_тип ) → double precision
Вычисляет площадь. Имеется для типов box, path, circle. Входное значение типа path должно быть замкнутым, иначе возвращается NULL. Кроме того, если этот путь является самопересекающимся, результат может не иметь смысла.
area(box '(2,2),(0,0)') → 4
center ( геометрический_тип ) → point
Вычисляет центральную точку. Имеется для типов box, circle.
center(box '(1,2),(0,0)') → (0.5,1)
diagonal ( box ) → lseg
Извлекает диагональ прямоугольника в виде отрезка (аналогично lseg(box)).
diagonal(box '(1,2),(0,0)') → [(1,2),(0,0)]
diameter ( circle ) → double precision
Вычисляет диаметр окружности.
diameter(circle '<(0,0),2>') → 4
height ( box ) → double precision
Вычисляет вертикальный размер прямоугольника.
height(box '(1,2),(0,0)') → 2
isclosed ( path ) → boolean
Путь замкнутый?
isclosed(path '((0,0),(1,1),(2,0))') → t
isopen ( path ) → boolean
Путь открытый?
isopen(path '[(0,0),(1,1),(2,0)]') → t
length ( геометрический_тип ) → double precision
Вычисляет общую длину. Имеется для типов lseg, path.
length(path '((-1,0),(1,0))') → 4
npoints ( геометрический_тип ) → integer
Возвращает количество точек. Имеется для типов path, polygon.
npoints(path '[(0,0),(1,1),(2,0)]') → 3
pclose ( path ) → path
Преобразует путь в замкнутую форму.
pclose(path '[(0,0),(1,1),(2,0)]') → ((0,0),(1,1),(2,0))
popen ( path ) → path
Преобразует путь в открытую форму.
popen(path '((0,0),(1,1),(2,0))') → [(0,0),(1,1),(2,0)]
radius ( circle ) → double precision
Вычисляет радиус окружности.
radius(circle '<(0,0),2>') → 2
slope ( point, point ) → double precision
Вычисляет наклон линии, проведенной через две точки.
slope(point '(0,0)', point '(2,1)') → 0.5
width ( box ) → double precision
Вычисляет горизонтальный размер прямоугольника.
width(box '(1,2),(0,0)') → 1

Таблица 37. Функции преобразования геометрических типов

Функция
Описание
Пример(ы)
box ( circle ) → box
Вычисляет прямоугольник, вписанный в окружность.
box(circle '<(0,0),2>') → (1.414213562373095,1.414213562373095),​(-1.414213562373095,-1.414213562373095)
box ( point ) → box
Преобразует точку в пустой прямоугольник.
box(point '(1,0)') → (1,0),(1,0)
box ( point, point ) → box
Преобразует любые две угловые точки в прямоугольник.
box(point '(0,1)', point '(1,0)') → (1,1),(0,0)
box ( polygon ) → box
Вычисляет окружающий прямоугольник для многоугольника.
box(polygon '((0,0),(1,1),(2,0))') → (2,1),(0,0)
bound_box ( box, box ) → box
Вычисляет окружающий прямоугольник для двух прямоугольников.
bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') → (4,4),(0,0)
circle ( box ) → circle
Вычисляет наименьшую окружность, вмещающую прямоугольник.
circle(box '(1,1),(0,0)') → <(0.5,0.5),0.7071067811865476>
circle ( point, double precision ) → circle
Строит окружность по центру и радиусу.
circle(point '(0,0)', 2.0) → <(0,0),2>
circle ( polygon ) → circle
Преобразует многоугольник в окружность. Центром окружности является среднее арифметическое координат вершин многоугольника, а радиусом — среднее расстояние от вершин многоугольника до этого центра.
circle(polygon '((0,0),(1,3),(2,0))') → <(1,1),1.6094757082487299>
line ( point, point ) → line
Преобразует две точки в проходящую через них линию.
line(point '(-1,0)', point '(1,0)') → {0,-1,0}
lseg ( box ) → lseg
Извлекает диагональ прямоугольника в виде отрезка.
lseg(box '(1,0),(-1,0)') → [(1,0),(-1,0)]
lseg ( point, point ) → lseg
Строит отрезок по двум конечным точкам.
lseg(point '(-1,0)', point '(1,0)') → [(-1,0),(1,0)]
path ( polygon ) → path
Преобразует многоугольник в замкнутый путь с тем же списком точек.
path(polygon '((0,0),(1,1),(2,0))') → ((0,0),(1,1),(2,0))
point ( double precision, double precision ) → point
Строит точку по заданным координатам.
point(23.4, -44.5) → (23.4,-44.5)
point ( box ) → point
Вычисляет центр прямоугольника.
point(box '(1,0),(-1,0)') → (0,0)
point ( circle ) → point
Вычисляет центр окружности.
point(circle '<(0,0),2>') → (0,0)
point ( lseg ) → point
Вычисляет центр отрезка.
point(lseg '[(-1,0),(1,0)]') → (0,0)
point ( polygon ) → point
Вычисляет центр многоугольника (среднее арифметическое координат его вершин).
point(polygon '((0,0),(1,1),(2,0))') → (1,0.3333333333333333)
polygon ( box ) → polygon
Преобразует прямоугольник в многоугольник с 4 вершинами.
polygon(box '(1,1),(0,0)') → ((0,0),(0,1),(1,1),(1,0))
polygon ( circle ) → polygon
Преобразует окружность в многоугольник с 12 вершинами.
polygon(circle '<(0,0),2>') → ((-2,0),​(-1.7320508075688774,0.9999999999999999),​(-1.0000000000000002,1.7320508075688772),​(-1.2246063538223773e-16,2),​(0.9999999999999996,1.7320508075688774),​(1.732050807568877,1.0000000000000007),​(2,2.4492127076447545e-16),​(1.7320508075688776,-0.9999999999999994),​(1.0000000000000009,-1.7320508075688767),​(3.673819061467132e-16,-2),​(-0.9999999999999987,-1.732050807568878),​(-1.7320508075688767,-1.0000000000000009))
polygon ( integer, circle ) → polygon
Преобразует окружность в многоугольник с n вершинами.
polygon(4, circle '<(3,0),1>') → ((2,0),​(3,1),​(4,1.2246063538223773e-16),​(3,-1))
polygon ( path ) → polygon
Преобразует замкнутый путь в многоугольник с тем же списком вершин.
polygon(path '((0,0),(1,1),(2,0))') → ((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.