как посчитать центр многоугольника

Created on: March 1, 2025

Answered using O1 by Chat01

Question

как посчитать центр многоугольника

Thought

Calculating polygon center

I’m calculating the centroid of a polygon using its vertex coordinates. The formulas involve sums of products and areas, reflecting the shape's mass distribution.

Reasoned about polygon centroid calculation for 5 seconds

Answer

Чтобы найти «центр» (центроид) простого (не самопересекающегося) многоугольника по заданным вершинам, обычно используют формулы для геометрического центра масс. Ниже приведён один из распространённых методов (иногда его называют «центроид произвольного многоугольника» или «центроид по площади»).


Обозначения

Пусть у нас есть многоугольник с вершинами (x0,y0),(x1,y1),,(xn1,yn1)(x_0, y_0), (x_1, y_1), \dots, (x_{n-1}, y_{n-1}). Предположим, что вершины идут по периметру в порядке обхода (по часовой или против часовой стрелки), и последний отрезок соединяет (xn1,yn1)(x_{n-1}, y_{n-1}) с (x0,y0)(x_0, y_0).

Площадь многоугольника

Сначала вычислим ориентированную площадь AA многоугольника по формуле Шоэна (Shoelace formula):

A=12i=0n1(xiyi+1xi+1yi),A = \frac{1}{2} \sum_{i=0}^{n-1} (x_i\,y_{i+1} - x_{i+1}\,y_i),

где xn=x0x_n = x_0 и yn=y0y_n = y_0 (чтобы замкнуть контур).

Важно: если обход вершин идёт против часовой стрелки, AA будет положительной; если по часовой – отрицательной. Для вычисления координат центра достаточно знать AA по модулю, но в формулах ниже учитывается ориентация.

Координаты центра (центроида)

После этого координаты центра (Cx,Cy)(C_x, C_y) задаются так:

Cx=16Ai=0n1(xi+xi+1)(xiyi+1xi+1yi),C_x = \frac{1}{6A} \sum_{i=0}^{n-1} (x_i + x_{i+1}) \, (x_i y_{i+1} - x_{i+1} y_i), Cy=16Ai=0n1(yi+yi+1)(xiyi+1xi+1yi).C_y = \frac{1}{6A} \sum_{i=0}^{n-1} (y_i + y_{i+1}) \, (x_i y_{i+1} - x_{i+1} y_i).

Если вы в итоге хотите получить «обычную» площадь (без знака) и «обычный» центр (без учёта направления обхода), то берите A\lvert A \rvert вместо AA в знаменателе.


Пример

Допустим, у нас есть треугольник с вершинами:

  1. (1,0)(1, 0)
  2. (3,0)(3, 0)
  3. (2,2)(2, 2)

Тогда:

  1. Вершины: (x0,y0)=(1,0)(x_0, y_0) = (1, 0), (x1,y1)=(3,0)(x_1, y_1) = (3, 0), (x2,y2)=(2,2)(x_2, y_2) = (2, 2).
  2. Замыкаем многоугольник: (x3,y3)=(x0,y0)=(1,0)(x_3, y_3) = (x_0, y_0) = (1, 0).
  • Считаем площадь AA:
A=12[(x0y1x1y0)+(x1y2x2y1)+(x2y3x3y2)].A = \frac{1}{2} \Big[ (x_0y_1 - x_1y_0) + (x_1y_2 - x_2y_1) + (x_2y_3 - x_3y_2) \Big].

Подставляя числа:

A=12[(1030)+(3220)+(2012)]=12[0+6+(2)]=12×4=2.A = \frac{1}{2} \Big[ (1 \cdot 0 - 3 \cdot 0) + (3 \cdot 2 - 2 \cdot 0) + (2 \cdot 0 - 1 \cdot 2) \Big] = \frac{1}{2} \Big[ 0 + 6 + (-2) \Big] = \frac{1}{2} \times 4 = 2.
  • Теперь координаты центроида:
Cx=16Ai=02(xi+xi+1)(xiyi+1xi+1yi).C_x = \frac{1}{6A} \,\sum_{i=0}^{2} (x_i + x_{i+1}) (x_i y_{i+1} - x_{i+1} y_i).

Вычислим пошагово:

  1. Для i=0i=0: (x0+x1)(x0y1x1y0)=(1+3)(1030)=4×0=0.(x_0 + x_1)(x_0 y_1 - x_1 y_0) = (1 + 3)(1 \cdot 0 - 3 \cdot 0) = 4 \times 0 = 0.
  2. Для i=1i=1: (x1+x2)(x1y2x2y1)=(3+2)(3220)=5×6=30.(x_1 + x_2)(x_1 y_2 - x_2 y_1) = (3 + 2)(3 \cdot 2 - 2 \cdot 0) = 5 \times 6 = 30.
  3. Для i=2i=2: (x2+x3)(x2y3x3y2)=(2+1)(2012)=3×(2)=6.(x_2 + x_3)(x_2 y_3 - x_3 y_2) = (2 + 1)(2 \cdot 0 - 1 \cdot 2) = 3 \times (-2) = -6.

Значит,

Cx=162(0+306)=2412=2.C_x = \frac{1}{6 \cdot 2} (0 + 30 - 6) = \frac{24}{12} = 2.

Аналогично для CyC_y:

Cy=16Ai=02(yi+yi+1)(xiyi+1xi+1yi).C_y = \frac{1}{6A} \,\sum_{i=0}^{2} (y_i + y_{i+1}) (x_i y_{i+1} - x_{i+1} y_i).
  1. Для i=0i=0: (y0+y1)(x0y1x1y0)=(0+0)(1030)=0.(y_0 + y_1)(x_0 y_1 - x_1 y_0) = (0 + 0)(1 \cdot 0 - 3 \cdot 0) = 0.
  2. Для i=1i=1: (y1+y2)(x1y2x2y1)=(0+2)(3220)=2×6=12.(y_1 + y_2)(x_1 y_2 - x_2 y_1) = (0 + 2)(3 \cdot 2 - 2 \cdot 0) = 2 \times 6 = 12.
  3. Для i=2i=2: (y2+y3)(x2y3x3y2)=(2+0)(2012)=2×(2)=4.(y_2 + y_3)(x_2 y_3 - x_3 y_2) = (2 + 0)(2 \cdot 0 - 1 \cdot 2) = 2 \times (-2) = -4.

Тогда

Cy=12462=812=230,6667.C_y = \frac{12 - 4}{6 \cdot 2} = \frac{8}{12} = \frac{2}{3} \approx 0{,}6667.

Итого координаты центра треугольника: (2,2/3)(2, 2/3).


Коротко о реализациях

  1. Ручное вычисление. Формулы выше можно посчитать вручную, если многоугольник небольшой.
  2. Программно. Во многих библиотеках (например, в геоинформационных системах, пакетах вычисления компьютерной графики и т.д.) есть готовые функции для нахождения центроида.

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


Важные детали

  • Эти формулы корректны для простых, не самопересекающихся многоугольников. Если многоугольник самопересекающийся или имеет «дырки», понадобится более сложный подход.
  • Если вы используете ориентированную площадь AA (которая может быть отрицательной), то получите правильный знак в формулах. Но часто просто берут абсолютное значение A\lvert A \rvert в знаменателе, чтобы не «запутаться» со знаком при поиске именно геометрического центра.
  • Если нужно найти другой «центр» (например, центр описанной или вписанной окружности, или центр bounding box), то это уже другие задачи и другие формулы.

Итог: чтобы посчитать «центр» (центроид по площади) многоугольника, достаточно:

  1. С помощью формулы «гауссовой площади» (Shoelace formula) найти AA.
  2. Подставить AA в формулы для CxC_x и CyC_y.
  3. Просуммировать соответствующие выражения по всем рёбрам и разделить на 6A6A.

Так вы получите координаты точки, которая является геометрическим центром (центром масс) данного плоского многоугольника.

Question

написать функцию на javascript нахождения центроида если приходит массив [[x, y],...[xn, yn]]

Answer

Вот пример простой функции на JavaScript, которая находит центроид многоугольника, заданного массивом координат вершин [[x0,y0],[x1,y1],...,[xn,yn]]:

javascript
function calculateCentroid(points) { let area = 0; let Cx = 0; let Cy = 0; const n = points.length; for (let i = 0; i < n; i++) { const [x0, y0] = points[i]; const [x1, y1] = points[(i + 1) % n]; const cross = (x0 * y1) - (x1 * y0); area += cross; Cx += (x0 + x1) * cross; Cy += (y0 + y1) * cross; } area /= 2; if (area === 0) { throw new Error('Area of polygon is zero (possibly degenerate polygon)'); } Cx /= (6 * area); Cy /= (6 * area); return [Cx, Cy]; } // Пример использования: const polygon = [[1,0], [3,0], [2,2]]; console.log(calculateCentroid(polygon)); // [2, 0.6666666666666666]

Объяснение:

  • Функция обходит все точки многоугольника и суммирует промежуточные значения для площади и координат.
  • В конце она вычисляет центроид по формулам, описанным выше.
  • Возвращает координаты [Cx, Cy].

Share this Q&A