Геометрические функции и операторы
Для геометрических типов point (точка), box (прямоугольник), lseg (отрезок), line (прямая), path (путь), polygon (многоугольник) и circle (окружность) существует большой набор встроенных вспомогательных функций и операторов, приведенных в подразделах Геометрические операторы, Геометрические функции и Функции преобразования геометрических типов.
Геометрические операторы
геометрический_тип + 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, box1, 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, box1, 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)
# геометрический_тип → integer
Возвращает количество точек. Имеется для типов path, polygon.
@@ box '(2,2),(0,0)' → (1,1)
геометрический_тип # геометрический_тип → point
Вычисляет точку пересечения или возвращает NULL, если точки пересечения нет. Имеется для типов lseg, line.
@@ 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
Вычисляет расстояние между объектами. Имеется для всех семи геометрических типов, для всех комбинаций типа 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
ВНИМАНИЕ!
Обратите внимание, что оператор «тождественности»,~=, представляет собой обычную проверку равенства для типов point, box, polygon и circle. Для некоторых геометрических типов также имеется оператор=, но=проверяет только равенство площадей. Другие скалярные операторы сравнения (<=и т. п.) для тех типов, для которых они имеются, также сравнивают площади.
Примечание
До QHB 1.5.2 операторы сравненияpoint <<| point(строго ниже) иpoint |>> point(строго выше) назывались<^и>^соответственно. Эти имена все еще доступны, но являются устаревшими и в итоге будут удалены.
Геометрические функции
area
area ( геометрический_тип ) → double precision
Вычисляет площадь. Имеется для типов box, path, circle. Входное значение типа path (путь) должно быть закрытым, иначе возвращается NULL. Кроме того, если этот путь является самопересекающимся, результат может не иметь смысла.
area(box '(2,2),(0,0)') → 4
center
center ( геометрический_тип ) → point
Вычисляет центральную точку. Имеется для типов box, circle.
center(box '(1,2),(0,0)') → (0.5,1)
diagonal
diagonal ( box ) → lseg
Извлекает диагональ прямоугольника в виде отрезка (аналогично lseg(box)).
diagonal(box '(1,2),(0,0)') → [(1,2),(0,0)]
diameter
diameter ( circle ) → double precision
Вычисляет диаметр окружности.
diameter(circle '<(0,0),2>') → 4
height
height ( box ) → double precision
Вычисляет вертикальный размер прямоугольника.
height(box '(1,2),(0,0)') → 2
isclosed
isclosed ( path ) → boolean
Это закрытый путь?
isclosed(path '((0,0),(1,1),(2,0))') → t
isopen
isopen ( path ) → boolean
Это открытый путь?
isopen(path '[(0,0),(1,1),(2,0)]') → t
length
length ( геометрический_тип ) → double precision
Вычисляет общую длину. Имеется для типов lseg, path.
length(path '((-1,0),(1,0))') → 4
npoints
npoints ( геометрический_тип ) → integer
Возвращает количество точек. Имеется для типов path, polygon.
npoints(path '[(0,0),(1,1),(2,0)]') → 3
pclose
pclose ( path ) → path
Преобразует путь в закрытую форму.
pclose(path '[(0,0),(1,1),(2,0)]') → ((0,0),(1,1),(2,0))
popen
popen ( path ) → path
Преобразует путь в открытую форму.
popen(path '((0,0),(1,1),(2,0))') → [(0,0),(1,1),(2,0)]
radius
radius ( circle ) → double precision
Вычисляет радиус окружности.
radius(circle '<(0,0),2>') → 2
slope
slope ( point, point ) → double precision
Вычисляет наклон линии, проведенной через две точки.
slope(point '(0,0)', point '(2,1)') → 0.5
width
width ( box ) → double precision
Вычисляет горизонтальный размер прямоугольника.
width(box '(1,2),(0,0)') → 1
Функции преобразования геометрических типов
box
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
bound_box ( box, box ) → box
Вычисляет окружающий прямоугольник для двух прямоугольников.
bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') → (4,4),(0,0)
circle
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
line ( point, point ) → line
Преобразует две точки в проходящую через них линию.
line(point '(-1,0)', point '(1,0)') → {0,-1,0}
lseg
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
path ( polygon ) → path
Преобразует многоугольник в закрытый путь с тем же списком точек.
path(polygon '((0,0),(1,1),(2,0))') → ((0,0),(1,1),(2,0))
point
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
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.