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

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

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

Геометрические типы point, box, lseg, line, path, polygon и circle имеют большой набор встроенных функций и операторов, показанных в таблице Таблица 9.36, Таблица 9.37 и Таблица 9.38.

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

Оператор

Описание

Пример(ы)

geometric_type + pointgeometric_type

Добавляет координаты второй точки point к координатам каждой точки первого аргумента, выполняя тем самым перевод. Доступно для point, box, path, circle.

box '(1,1),(0,0)' + point '(2,0)'(3,1),(2,0)

path + pathpath

Соединяет два открытых пути (возвращает NULL, если хотя бы один путь закрыт).

path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]'[(0,0),(1,1),(2,2),(3,3),(4,4)]

geometric_type - pointgeometric_type

Вычитает координаты второй точки point из координат каждой точки первого аргумента, выполняя тем самым перевод. Доступно для point, box, path, circle.

box '(1,1),(0,0)' - point '(2,0)'(-1,1),(-2,0)

geometric_type * pointgeometric_type

Умножает каждую точку первого аргумента на вторую точку (рассматривая точку как комплексное число, представленное действительной и мнимой частями, и выполняя стандартное комплексное умножение). Если вторую точку интерпретировать как вектор, то это эквивалентно масштабированию размера объекта и расстояния от начала координат на длину вектора и повороту его против часовой стрелки вокруг начала координат на угол вектора от оси x. Доступно для точки, прямоугольника, [a] путь, круг.

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))

geometric_type / pointgeometric_type

Разделяет каждую точку первого аргумента на вторую точку (рассматривая точку как комплексное число, представленное действительной и мнимой частями, и выполняя стандартное комплексное деление). Если вторую точку интерпретировать как вектор, это эквивалентно масштабированию размера объекта и расстояния от начала координат на длину вектора и повороту его по часовой стрелке вокруг начала координат на угол вектора от оси x. Доступно для точки, прямоугольника, [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))

@-@ geometric_typedouble precision

Вычисляет общую длину. Доступно для lseg, path.

@-@ путь '[(0,0),(1,0),(1,1)]'2

@@ geometric_typepoint

Вычисляет центральную точку. Доступно для box, lseg, polygon, circle.

@@ box '(2,2),(0,0)'(1,1)

# geometric_typeinteger

Возвращает количество точек. Доступно для пути, полигона.

# путь '((1,0),(0,1),(-1,0))'3

geometric_type # geometric_typepoint

Вычисляет точку пересечения или NULL, если она отсутствует. Доступно для типов lseg и line.

lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]'(0.5,0.5)

box # boxbox

Вычисляет пересечение двух прямоугольников или возвращает NULL, если пересечения нет.

box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)'(1,1),(-1,-1)

geometric_type ## geometric_typepoint

Вычисляет ближайшую точку к первому объекту на втором объекте. Доступно для следующих пар типов: (point, box), (point, lseg), (point, line), (lseg, box), (lseg, lseg), (line, lseg).

point '(0,0)' ## lseg '[(2,0),(0,2)]'(1,1)

geometric_type <-> geometric_typedouble precision

Вычисляет расстояние между объектами. Доступно для всех семи геометрических типов, для всех комбинаций типа point с другим геометрическим типом, а также для следующих дополнительных пар типов: (box, lseg), (lseg, line), (polygon, circle) (и коммутативные случаи).

circle '<(0,0),1>' <-> circle '<(5,0),1>'3

geometric_type @> geometric_typeboolean

Содержит ли первый объект второй? Доступно для следующих пар типов: (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_typeboolean

Перевод с сохранением форматирования: {Первый объект содержится внутри или на втором? Доступно для следующих пар типов: (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_typeboolean

Перекрываются ли эти объекты? (Один общий точка делает это верным). Доступно для box, polygon, circle.

box '(1,1),(0,0)' && box '(2,2),(0,0)'t

geometric_type << geometric_typeboolean

Является ли первый объект строго слева от второго? Доступно для точки, прямоугольника, полигона, круга.

circle '<(0,0),1>' << circle '<(5,0),1>'t

geometric_type >> geometric_typeboolean

Является ли первый объект строго правее второго? Доступно для point, box, polygon, circle.

circle '<(5,0),1>' >> circle '<(0,0),1>'t

geometric_type &< geometric_typeboolean

Не распространяется ли первый объект вправо от второго? Доступно для box, polygon, circle.

box '(1,1),(0,0)' &< box '(2,2),(0,0)'t

geometric_type &> geometric_typeboolean

Не распространяется ли первый объект влево от второго? Доступно для box, polygon, circle.

box '(3,3),(0,0)' &> box '(2,2),(0,0)'t

geometric_type <<| geometric_typeboolean

Является ли первый объект строго ниже второго? Доступно для точки, прямоугольника, полигона, круга.

box '(3,3),(0,0)' <<| box '(5,5),(3,4)'t

geometric_type |>> geometric_typeboolean

Является ли первый объект строго выше второго? Доступно для точки, прямоугольника, полигона, круга.

box '(5,5),(3,4)' |>> box '(3,3),(0,0)'t

geometric_type &<| geometric_typeboolean

Не распространяется ли первый объект выше второго? Доступно для box, polygon, circle.

box '(1,1),(0,0)' &<| box '(2,2),(0,0)'t

geometric_type |&> geometric_typeboolean

Не распространяется ли первый объект ниже второго? Доступно для box, polygon, circle.

box '(3,3),(0,0)' |&> box '(2,2),(0,0)'t

box <^ boxboolean

Первый объект ниже второго (позволяет касаться граням)?

box '((1,1),(0,0))' <^ box '((2,2),(1,1))'t

box >^ boxboolean

Является ли первый объект выше второго (позволяет касаться граней)?

box '((2,2),(1,1))' >^ box '((1,1),(0,0))'t

geometric_type ?# geometric_typeboolean

Эти объекты пересекаются? Доступно для следующих пар типов: (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

?- lineboolean

?- lsegboolean

Является ли линия горизонтальной?

?- lseg '[(-1,0),(1,0)]'t

point ?- pointboolean

Выровнены ли точки горизонтально (то есть, имеют одинаковую координату y)?

point '(1,0)' ?- point '(0,0)'t

?| lineboolean

?| lsegboolean

Является ли линия вертикальной?

?| lseg '[(-1,0),(1,0)]'f

point ?| pointboolean

Вертикально ли выровнены точки (то есть, имеют одинаковую x-координату)?

point '(0,1)' ?| point '(0,0)'t

line ?-| lineboolean

lseg ?-| lsegboolean

Являются ли линии перпендикулярными?

lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]'t

line ?|| lineboolean

lseg ?|| lsegboolean

Являются ли линии параллельными?

lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]'t

geometric_type ~= geometric_typeboolean

Эти объекты одинаковы? Доступно для point, box, polygon, circle.

polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'t

[a] Вращение коробки с помощью этих операторов перемещает только ее угловые точки: коробка все еще считается имеющей стороны, параллельные осям. Таким образом, размер коробки не сохраняется, как это делалось бы при настоящем вращении.


Предостережение

Обратите внимание, что оператор same as, ~=, представляет обычное понятие равенства для типов point, box, polygon и circle. Некоторые геометрические типы также имеют оператор =, но = сравнивает только площади. Другие операторы сравнения скаляров (<= и так далее), если они доступны для этих типов, также сравнивают площади.

Примечание

Перед Tantor SE 14 точка строго ниже/выше операторов сравнения point <<| point и point |>> point соответственно назывались <^ и >^. Эти имена по-прежнему доступны, но устарели и в конечном итоге будут удалены.

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

Функция

Описание

Пример(ы)

area ( geometric_type ) → double precision

Вычисляет площадь. Доступно для box, path, circle. Входной параметр path должен быть замкнутым, иначе будет возвращено значение NULL. Также, если path имеет самопересечения, результат может быть бессмысленным.

area(box '(2,2),(0,0)')4

center ( geometric_type ) → 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 ( geometric_type ) → double precision

Вычисляет общую длину. Доступно для lseg, path.

length(path '((-1,0),(1,0))')4

npoints ( geometric_type ) → integer

Возвращает количество точек. Доступно для пути, полигона.

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


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

Функция

Описание

Пример(ы)

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).

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.