Из Википедии :
Центроид несамопересекающегося замкнутого многоугольника, определенного n вершинами ( x 0 , y 0 ), ( x 1 , y 1 ), ..., ( x n - 1 , y n − 1 ), является точка ( C x , C y ), где
и где A - площадь со знаком полигона,
В этих формулах предполагается, что вершины пронумерованы в порядке их появления по периметру многоугольника. Кроме того, предполагается , что вершина ( x n , y n ) совпадает с ( x 0 , y 0 ), что означает, что i + 1 в последнем случае должно повторяться до i = 0 . Обратите внимание, что если точки нумеруются по часовой стрелке, область A , вычисленная, как указано выше, будет иметь отрицательный знак; но координаты центроида будут правильными даже в этом случае.
- Учитывая список вершин по порядку (по часовой стрелке или против часовой стрелки), найдите центр тяжести несамопересекающегося замкнутого многоугольника, представленного вершинами.
- Если это помогает, вы можете считать, что вводом является только CW или только CCW. Скажи так в своем ответе, если вам это нужно.
- Координаты не обязательно должны быть целыми числами и могут содержать отрицательные числа.
- Ввод всегда будет действительным и содержать как минимум три вершины.
- Входные данные должны обрабатываться только в соответствии с типом данных с плавающей запятой вашего языка.
- Вы можете предположить, что входные числа всегда будут содержать десятичную точку.
- Вы можете предположить, что входные целые числа заканчиваются на
.
или.0
. - Вы можете использовать комплексные числа для ввода.
- Вывод должен быть точным с точностью до тысячных.
Примеры
[(0.,0.), (1.,0.), (1.,1.), (0.,1.)] -> (0.5, 0.5)
[(-15.21,0.8), (10.1,-0.3), (-0.07,23.55)] -> -1.727 8.017
[(-39.00,-55.94), (-56.08,-4.73), (-72.64,12.12), (-31.04,53.58), (-30.36,28.29), (17.96,59.17), (0.00,0.00), (10.00,0.00), (20.00,0.00), (148.63,114.32), (8.06,-41.04), (-41.25,34.43)] -> 5.80104769975, 15.0673812762
Чтобы увидеть каждый многоугольник на координатной плоскости, вставьте координаты без квадратных скобок в меню «Правка» этой страницы .
Я подтвердил свои результаты, используя этот многоугольный калькулятор точек центроида , который ужасен. Я не смог найти тот, в который можно было бы ввести все вершины одновременно, или который не пытался стереть свой -
знак при первом его вводе . Я опубликую свое решение Python для вашего использования после того, как у людей будет возможность ответить.
x
s иy
s помещает весь вес в вершины, а не распределяется по телу. Первый из них работает, потому что он регулярный, поэтому оба метода оказываются в центре симметрии. Второй работает, потому что для треугольников оба метода приводят к одной и той же точке.Ответы:
Желе ,
2524222118 байтПрименяет формулу, показанную в задаче.
Сохранено 3 байта с помощью @ Джонатана Аллана.
Попробуйте онлайн!или Проверьте все контрольные примеры.
объяснение
источник
ṁL‘$ṡ2
наṙ1ż@
илиżṙ1$
ṙ-ż
чтобы избежать обмена и сохранить еще один байтMathematica, 23 байта
принимать ТО , желе!Изменить: не просто победить желе ...
объяснение
Создайте многоугольник с вершинами в указанных точках.
Найдите центр тяжести многоугольника.
источник
J, 29 байт
Применяет формулу, показанную в задаче.
использование
объяснение
источник
Максима,
124 118 116 112106 байтУ меня нет опыта работы с Maxima, поэтому любые советы приветствуются.
Использование:
источник
Ракетка 420 байт
Ungolfed:
Тестирование:
Выход:
источник
R
129 129байтБезымянная функция, которая принимает R-список кортежей в качестве входных данных. Названный эквивалент может быть вызван с помощью, например:
Разгромил и объяснил
Последний шаг (
c(sum((x+X)*p),sum((y+Y)*p))/sum(p)*2/6
) - векторизованный способ вычисленияCx
иCy
. Сумма в формулахCx
иCy
хранится в векторе и, следовательно, делится на «сумму вA
»*2/6
. Например:, а затем неявно печатается.
Попробуйте это на R-скрипке
источник
*2/6
может быть/3
?sapply
для работы с этими списками! Здесь могут быть возможности для игры в гольф, я не уверен, насколько гибок допустимый вклад. Если вам разрешено вводить только последовательность координат, напримерc(-15.21,0.8,10.1,-0.3,-0.07,23.55)
, вы можете сохранить 17 байтов, заменив первые строки вашей функции наy=l[s<-seq(2,sum(1|l),2)];x=l[-s];
. Таким образом, установкаy
каждого элемента с четным индексомl
иx
каждого элемента с нечетным индексом.matrix(c(-15.21,0.8,10.1,-0.3,-0.07,23.55),2)
, например , начало вашей функцииx=l[1,];y=l[2,];
, которое экономит 35 байт. (Вход матрица может быть перенесена, и в этом случаеx=l[,1];y=l[,2];
.) Конечно, самое простое решение все есть , еслиx
иy
пункты просто вводятся как отдельные векторы,function(x,y)
, но я не думаю , что это разрешено ...c(...)
), и преобразование матрицы должно было бы быть сделано внутри функции.Python,
156127 байтUngolfed:
Идео это.
Это принимает каждую пару точек
[x, y]
в качестве комплексного числаx + y*j
и выводит полученный центроид как комплексное число в том же формате.Для пары точек
[a, b]
и[c, d]
значение,a*d - b*c
необходимое для каждой пары точек, может быть вычислено из определителя матрицыИспользуя сложную арифметику, комплексные значения
a + b*j
иc + d*j
могут быть использованы какОбратите внимание, что мнимая часть эквивалентна определителю. Кроме того, использование комплексных значений позволяет легко суммировать точки в других операциях.
источник
R + sp (46 байт)
Предполагается, что
sp
пакет установлен ( https://cran.r-project.org/web/packages/sp/ )Принимает список вершин, (например
list(c(0.,0.), c(1.,0.), c(1.,1.), c(0.,1.))
)Использует тот факт, что "labpt" полигона является центроид.
источник
JavaScript (ES6), 102
Прямая реализация формулы
Тестовое задание
источник
Python 2, 153 байта
Не использует комплексные числа.
Попробуйте онлайн
Ungolfed:
источник
На самом деле,
454039 байтПри этом используется алгоритм, аналогичный ответу желе миль . Существует более короткий способ вычисления определителей с использованием точечного продукта, но в настоящее время существует ошибка с точечным продуктом Actually, когда он не работает со списками с плавающей точкой. Предложения по игре в гольф приветствуются. Попробуйте онлайн!
Ungolfing
Короче, неконкурентная версия
Это еще одна 24-байтовая версия, которая использует комплексные числа. Он неконкурентоспособен, потому что он опирается на исправления ошибок, которые датируют эту проблему. Попробуйте онлайн!
Ungolfing
источник
C ++ 14, 241 байт
Выход является вспомогательной структурой
P
,Ungolfed:
Использование:
источник
Clojure,
177156143 байтаОбновление: вместо обратного вызова я использую
[a b c d 1]
функцию, а аргумент - это просто список индексов для этого вектора.1
используется в качестве дозорного значения при расчетеA
.Обновление 2: Не предварительное вычисление
A
наlet
, используя(rest(cycle %))
для получения входных векторов смещения на единице.Оригинальная версия:
На менее гольфовой стадии:
Создает вспомогательную функцию
F
которая реализует суммирование с любым обратным вызовомl
. ПосколькуA
обратный вызов возвращается постоянно,1
тогда как координаты X и Y имеют свои функции.(conj(subvec v 1)(v 0))
удаляет первый элемент и добавляет в конец, таким образом, легко отслеживатьx_i
иx_(i+1)
. Может быть, еще есть какое-то повторение, особенно в последний раз(map F[...
.источник