Geometry2D

Наследует: Object

Предоставляет методы для некоторых распространенных двумерных геометрических операций.

Описание

Предоставляет набор вспомогательных функций для создания геометрических фигур, вычисления пересечений между фигурами и обработки различных других геометрических операций в 2D.

Методы

Array[Vector2i]

bresenham_line(from: Vector2i, to: Vector2i)

Array[PackedVector2Array]

clip_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array)

Array[PackedVector2Array]

clip_polyline_with_polygon(polyline: PackedVector2Array, polygon: PackedVector2Array)

PackedVector2Array

convex_hull(points: PackedVector2Array)

Array[PackedVector2Array]

decompose_polygon_in_convex(polygon: PackedVector2Array)

Array[PackedVector2Array]

exclude_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array)

Vector2

get_closest_point_to_segment(point: Vector2, s1: Vector2, s2: Vector2)

Vector2

get_closest_point_to_segment_uncapped(point: Vector2, s1: Vector2, s2: Vector2)

PackedVector2Array

get_closest_points_between_segments(p1: Vector2, q1: Vector2, p2: Vector2, q2: Vector2)

Array[PackedVector2Array]

intersect_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array)

Array[PackedVector2Array]

intersect_polyline_with_polygon(polyline: PackedVector2Array, polygon: PackedVector2Array)

bool

is_point_in_circle(point: Vector2, circle_position: Vector2, circle_radius: float)

bool

is_point_in_polygon(point: Vector2, polygon: PackedVector2Array)

bool

is_polygon_clockwise(polygon: PackedVector2Array)

Variant

line_intersects_line(from_a: Vector2, dir_a: Vector2, from_b: Vector2, dir_b: Vector2)

Dictionary

make_atlas(sizes: PackedVector2Array)

Array[PackedVector2Array]

merge_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array)

Array[PackedVector2Array]

offset_polygon(polygon: PackedVector2Array, delta: float, join_type: PolyJoinType = 0)

Array[PackedVector2Array]

offset_polyline(polyline: PackedVector2Array, delta: float, join_type: PolyJoinType = 0, end_type: PolyEndType = 3)

bool

point_is_inside_triangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2) const

float

segment_intersects_circle(segment_from: Vector2, segment_to: Vector2, circle_position: Vector2, circle_radius: float)

Variant

segment_intersects_segment(from_a: Vector2, to_a: Vector2, from_b: Vector2, to_b: Vector2)

PackedInt32Array

triangulate_delaunay(points: PackedVector2Array)

PackedInt32Array

triangulate_polygon(polygon: PackedVector2Array)


Перечисления

enum PolyBooleanOperation: 🔗

PolyBooleanOperation OPERATION_UNION = 0

Создайте области, в которых заполнены либо объектные, либо отсекающие полигоны (или и те, и другие).

PolyBooleanOperation OPERATION_DIFFERENCE = 1

Создайте области, в которых заполнены полигоны субъекта, за исключением областей, где заполнены полигоны обрезки.

PolyBooleanOperation OPERATION_INTERSECTION = 2

Создайте области, в которых заполнены как полигоны объекта, так и полигоны клипа.

PolyBooleanOperation OPERATION_XOR = 3

Создавайте области, в которых заполнены либо полигоны объекта, либо полигоны обрезки, но не области, в которых заполнены оба полигона.


enum PolyJoinType: 🔗

PolyJoinType JOIN_SQUARE = 0

Возведение в квадрат применяется равномерно ко всем выпуклым ребрам при 1 * delta.

PolyJoinType JOIN_ROUND = 1

Хотя сглаженные траектории никогда не могут идеально описывать дугу, они аппроксимируются серией хорд дуг.

PolyJoinType JOIN_MITER = 2

Существует необходимый предел для соединений под углом, поскольку смещение кромок, которые соединяются под очень острыми углами, приведет к образованию чрезмерно длинных и узких «шипов». Для любого соединения кромок, если смещение под углом превышает максимальное расстояние, применяется «квадратное» соединение.


enum PolyEndType: 🔗

PolyEndType END_POLYGON = 0

Конечные точки соединяются с использованием значения PolyJoinType, а путь заполняется в виде многоугольника.

PolyEndType END_JOINED = 1

Конечные точки соединяются с использованием значения PolyJoinType, а путь заполняется в виде полилинии.

PolyEndType END_BUTT = 2

Конечные точки имеют квадратную форму и не имеют расширения.

PolyEndType END_SQUARE = 3

Конечные точки возводятся в квадрат и расширяются на единицы delta.

PolyEndType END_ROUND = 4

Конечные точки округляются и расширяются на единицы delta.


Описания метода

Array[Vector2i] bresenham_line(from: Vector2i, to: Vector2i) 🔗

Возвращает линию Брезенхэма между точками from и to. Линия Брезенхэма — это ряд пикселей, которые рисуют линию и всегда имеют толщину 1 пиксель в каждой строке и столбце чертежа (ни больше, ни меньше).

Пример кода для рисования линии между двумя узлами Marker2D с использованием ряда вызовов CanvasItem.draw_rect():

func _draw():
    for pixel in Geometry2D.bresenham_line($MarkerA.position, $MarkerB.position):
        draw_rect(Rect2(pixel, Vector2.ONE), Color.WHITE)

Array[PackedVector2Array] clip_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array) 🔗

Обрезает polygon_a по polygon_b и возвращает массив обрезанных полигонов. Это выполняет OPERATION_DIFFERENCE между полигонами. Возвращает пустой массив, если polygon_b полностью перекрывает polygon_a.

Если polygon_b заключен в polygon_a, возвращает внешний полигон (границу) и внутренний полигон (отверстие), которые можно различить, вызвав is_polygon_clock().


Array[PackedVector2Array] clip_polyline_with_polygon(polyline: PackedVector2Array, polygon: PackedVector2Array) 🔗

Обрезает polyline по polygon и возвращает массив обрезанных полилиний. Это выполняет OPERATION_DIFFERENCE между полилинией и полигоном. Эту операцию можно рассматривать как разрезание линии с замкнутой формой.


PackedVector2Array convex_hull(points: PackedVector2Array) 🔗

Учитывая массив Vector2, возвращает выпуклую оболочку как список точек в порядке против часовой стрелки. Последняя точка совпадает с первой.


Array[PackedVector2Array] decompose_polygon_in_convex(polygon: PackedVector2Array) 🔗

Разбивает polygon на несколько выпуклых оболочек и возвращает массив PackedVector2Array.


Array[PackedVector2Array] exclude_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array) 🔗

Взаимно исключает общую область, определенную пересечением polygon_a и polygon_b (см. intersect_polygons()), и возвращает массив исключенных полигонов. Это выполняет OPERATION_XOR между полигонами. Другими словами, возвращает все, кроме общей области между полигонами.

Операция может привести к получению внешнего полигона (границы) и внутреннего полигона (отверстия), которые можно различить, вызвав is_polygon_clock().


Vector2 get_closest_point_to_segment(point: Vector2, s1: Vector2, s2: Vector2) 🔗

Возвращает 2D-точку на 2D-сегменте (s1, s2), которая находится ближе всего к point. Возвращаемая точка всегда будет находиться внутри указанного сегмента.


Vector2 get_closest_point_to_segment_uncapped(point: Vector2, s1: Vector2, s2: Vector2) 🔗

Возвращает 2D-точку на 2D-линии, определенной (s1, s2), которая находится ближе всего к point. Возвращаемая точка может находиться внутри сегмента (s1, s2) или за его пределами, т. е. где-то на линии, выходящей из сегмента.


PackedVector2Array get_closest_points_between_segments(p1: Vector2, q1: Vector2, p2: Vector2, q2: Vector2) 🔗

Учитывая два 2D-сегмента (p1, q1) и (p2, q2), находит те две точки на двух сегментах, которые находятся ближе всего друг к другу. Возвращает PackedVector2Array, который содержит эту точку на (p1, q1), а также сопутствующую точку на (p2, q2).


Array[PackedVector2Array] intersect_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array) 🔗

Пересекает polygon_a с polygon_b и возвращает массив пересеченных полигонов. Это выполняет OPERATION_INTERSECTION между полигонами. Другими словами, возвращает общую область, разделяемую полигонами. Возвращает пустой массив, если пересечения не происходит.

Операция может привести к получению внешнего полигона (границы) и внутреннего полигона (отверстия), которые можно различить, вызвав is_polygon_clock().


Array[PackedVector2Array] intersect_polyline_with_polygon(polyline: PackedVector2Array, polygon: PackedVector2Array) 🔗

Пересекает polyline с polygon и возвращает массив пересеченных полилиний. Это выполняет OPERATION_INTERSECTION между полилинией и полигоном. Эту операцию можно рассматривать как нарезание линии замкнутой формой.


bool is_point_in_circle(point: Vector2, circle_position: Vector2, circle_radius: float) 🔗

Возвращает true, если point находится внутри круга или если он расположен точно на границе круга, в противном случае возвращает false.


bool is_point_in_polygon(point: Vector2, polygon: PackedVector2Array) 🔗

Возвращает true, если point находится внутри polygon или если она расположена точно на границе полигона, в противном случае возвращает false.


bool is_polygon_clockwise(polygon: PackedVector2Array) 🔗

Возвращает true, если вершины polygon упорядочены по часовой стрелке, в противном случае возвращает false.

Примечание: Предполагается декартова система координат, где +x — справа, а +y — сверху. При использовании экранных координат (+y — снизу), результат необходимо будет перевернуть (т. е. результат true будет указывать против часовой стрелки).


Variant line_intersects_line(from_a: Vector2, dir_a: Vector2, from_b: Vector2, dir_b: Vector2) 🔗

Возвращает точку пересечения между двумя линиями (from_a, dir_a) и (from_b, dir_b). Возвращает Vector2 или null, если линии параллельны.

from и dir являются не конечными точками отрезка линии или луча, а наклоном (dir) и известной точкой (from) на этой линии.

var from_a = Vector2.ZERO
var dir_a = Vector2.RIGHT
var from_b = Vector2.DOWN

# Возвращает Vector2(1, 0)
Geometry2D.line_intersects_line(from_a, dir_a, from_b, Vector2(1, -1))
# Возвращает Vector2(-1, 0)
Geometry2D.line_intersects_line(from_a, dir_a, from_b, Vector2(-1, -1))
# Возвращает null
Geometry2D.line_intersects_line(from_a, dir_a, from_b, Vector2.RIGHT)

Dictionary make_atlas(sizes: PackedVector2Array) 🔗

Учитывая массив Vector2, представляющий тайлы, создает атлас. Возвращаемый словарь имеет два ключа: points — это PackedVector2Array, который определяет позиции каждого тайла, и size содержит общий размер всего атласа как Vector2i.


Array[PackedVector2Array] merge_polygons(polygon_a: PackedVector2Array, polygon_b: PackedVector2Array) 🔗

Объединяет (комбинирует) polygon_a и polygon_b и возвращает массив объединенных полигонов. Это выполняет OPERATION_UNION между полигонами.

Операция может привести к образованию внешнего полигона (границы) и нескольких внутренних полигонов (отверстий), которые можно различить, вызвав is_polygon_clock().


Array[PackedVector2Array] offset_polygon(polygon: PackedVector2Array, delta: float, join_type: PolyJoinType = 0) 🔗

Раздувает или сдувает polygon на delta единиц (пикселей). Если delta положительно, то полигон растет наружу. Если delta отрицательно, то полигон сжимается внутрь. Возвращает массив полигонов, поскольку раздувание/сдувание может привести к появлению нескольких дискретных полигонов. Возвращает пустой массив, если delta отрицательно и его абсолютное значение приблизительно превышает минимальные размеры ограничивающего прямоугольника полигона.

Вершины каждого полигона будут округлены, как определено join_type.

Операция может привести к получению внешнего полигона (границы) и внутреннего полигона (отверстия), которые можно различить, вызвав is_polygon_clock().

Примечание: Чтобы переместить вершины полигона конкретно, умножьте их на Transform2D:

var polygon = PackedVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(100, 100), Vector2(0, 100)])
var offset = Vector2(50, 50)
polygon = Transform2D(0, offset) * polygon
print(polygon) # Выводит [(50.0, 50.0), (150.0, 50.0), (150.0, 150.0), (50.0, 150.0)]

Array[PackedVector2Array] offset_polyline(polyline: PackedVector2Array, delta: float, join_type: PolyJoinType = 0, end_type: PolyEndType = 3) 🔗

Раздувает или сдувает polyline на delta единиц (пикселей), создавая полигоны. Если delta положительно, полилиния растет наружу. Возвращает массив полигонов, поскольку раздувание/сдувание может привести к появлению нескольких дискретных полигонов. Если delta отрицательно, возвращает пустой массив.

Вершины каждого полигона будут округлены, как определено join_type.

Конечные точки каждого полигона будут округлены, как определено end_type.

В результате операции могут быть получены внешний полигон (граница) и внутренний полигон (отверстие), которые можно различить, вызвав is_polygon_clock().


bool point_is_inside_triangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2) const 🔗

Возвращает, если point находится внутри треугольника, заданного a, b и c.


float segment_intersects_circle(segment_from: Vector2, segment_to: Vector2, circle_position: Vector2, circle_radius: float) 🔗

Учитывая 2D-сегмент (segment_from, segment_to), возвращает позицию на сегменте (как число от 0 до 1), в которой сегмент касается окружности, расположенной в позиции circle_position и имеющей радиус circle_radius. Если сегмент не пересекает окружность, возвращается -1 (это также имеет место, если линия, продолжающая сегмент, пересекает окружность, но не пересекает сегмент).


Variant segment_intersects_segment(from_a: Vector2, to_a: Vector2, from_b: Vector2, to_b: Vector2) 🔗

Проверяет, пересекаются ли два сегмента (from_a, to_a) и (from_b, to_b). Если да, возвращает точку пересечения как Vector2. Если пересечения не происходит, возвращает null.


PackedInt32Array triangulate_delaunay(points: PackedVector2Array) 🔗

Триангулирует область, указанную дискретным набором points, таким образом, что ни одна точка не находится внутри описанной окружности любого полученного треугольника. Возвращает PackedInt32Array, где каждый треугольник состоит из трех последовательных индексов точек в points (т. е. возвращаемый массив будет иметь n * 3 элементов, где n — количество найденных треугольников). Если триангуляция не удалась, возвращается пустой PackedInt32Array.


PackedInt32Array triangulate_polygon(polygon: PackedVector2Array) 🔗

Триангулирует многоугольник, указанный точками в polygon. Возвращает PackedInt32Array, где каждый треугольник состоит из трех последовательных индексов точек в polygon (т. е. возвращаемый массив будет иметь n * 3 элементов, где n — количество найденных треугольников). Выходные треугольники всегда будут против часовой стрелки, а контур будет перевернут, если он по часовой стрелке. Если триангуляция не удалась, возвращается пустой PackedInt32Array.