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

Для геометрических типов 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.