Z Wikipedii :
Środek ciężkości nie-przecinającego się zamkniętego wielokąta zdefiniowanego przez n wierzchołków ( x 0 , y 0 ), ( x 1 , y 1 ), ..., ( x n - 1 , y n − 1 ) to punkt ( C x , C y ), gdzie
i gdzie A jest obszarem podpisanym wielokąta,
W tych wzorach zakłada się, że wierzchołki są ponumerowane w kolejności ich występowania wzdłuż obwodu wielokąta. Ponadto zakłada się , że wierzchołek ( x n , y n ) jest taki sam jak ( x 0 , y 0 ), co oznacza, że i + 1 w ostatnim przypadku musi zapętlić się wokół i = 0 . Zauważ, że jeśli punkty są ponumerowane w kolejności zgodnej z ruchem wskazówek zegara, obszar A , obliczony jak powyżej, będzie miał znak ujemny; ale współrzędne środka ciężkości będą prawidłowe nawet w tym przypadku.
- Biorąc pod uwagę listę wierzchołków w kolejności (zgodnie z ruchem wskazówek zegara lub przeciwnie do ruchu wskazówek zegara), znajdź środek ciężkości zamkniętego wielokąta zamkniętego reprezentowanego przez wierzchołki.
- Jeśli to pomoże, możesz założyć, że dane wejściowe to tylko CW lub tylko CCW. Powiedz to w swojej odpowiedzi, jeśli tego potrzebujesz.
- Współrzędne nie muszą być liczbami całkowitymi i mogą zawierać liczby ujemne.
- Dane wejściowe zawsze będą prawidłowe i będą zawierać co najmniej trzy wierzchołki.
- Dane wejściowe muszą być obsługiwane tylko w przypadku rodzimego typu danych zmiennoprzecinkowych w Twoim języku.
- Możesz założyć, że liczby wejściowe zawsze będą zawierały przecinek dziesiętny.
- Możesz założyć, że wejściowe liczby całkowite kończą się na
.
lub.0
. - Możesz używać liczb zespolonych do wprowadzania danych.
- Dane wyjściowe powinny być dokładne z dokładnością do jednej tysięcznej.
Przykłady
[(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
Aby zobaczyć każdy wielokąt na płaszczyźnie współrzędnych, wklej współrzędne bez nawiasów kwadratowych w menu „Edytuj” na tej stronie .
Potwierdziłem swoje wyniki za pomocą tego kalkulatora punktów wielokąta , który jest okropny. Nie mogłem znaleźć takiego, w którym można wprowadzić wszystkie wierzchołki naraz, lub który nie próbował wymazać twojego -
znaku przy pierwszym wpisaniu. Opublikuję moje rozwiązanie Python do użytku po tym, jak ludzie będą mieli okazję odpowiedzieć.
x
si iy
s umieszcza cały ciężar w wierzchołkach zamiast rozkładać je na ciele. Pierwszy przypadek działa, ponieważ jest regularny, więc obie metody kończą się w centrum symetrii. Drugi działa, ponieważ w przypadku trójkątów obie metody prowadzą do tego samego punktu.Odpowiedzi:
Galaretka ,
2524222118 bajtówStosuje wzór przedstawiony w problemie.
Zaoszczędź 3 bajty z pomocą @ Jonathan Allan.
Wypróbuj online! lub Zweryfikuj wszystkie przypadki testowe.
Wyjaśnienie
źródło
ṁL‘$ṡ2
przezṙ1ż@
lubżṙ1$
ṙ-ż
aby uniknąć wymiany i zaoszczędzić kolejny bajtMathematica, 23 bajty
Weź to , galaretka!Edycja: Nie wystarczy pokonać Galaretkę ...
Wyjaśnienie
Wygeneruj wielokąt z wierzchołkami we wskazanych punktach.
Znajdź środek ciężkości wielokąta.
źródło
J, 29 bajtów
Stosuje wzór przedstawiony w problemie.
Stosowanie
Wyjaśnienie
źródło
Maxima,
124 118 116 112106 bajtówNie mam doświadczenia z Maximą, więc wszelkie wskazówki są mile widziane.
Stosowanie:
źródło
Rakieta 420 bajtów
Nie golfowany:
Testowanie:
Wynik:
źródło
R,
129127 bajtówNienazwana funkcja, która pobiera listę R krotek jako dane wejściowe. Nazwany odpowiednik można wywołać za pomocą np .:
Nie golfił i wyjaśnił
Ostatni krok (
c(sum((x+X)*p),sum((y+Y)*p))/sum(p)*2/6
) to wektorowy sposób obliczania zarówno, jakCx
iCy
. Suma we wzorach dlaCx
iCy
jest przechowywana w wektorze, a zatem dzielona przez „suma wA
”*2/6
. Na przykład:, a następnie domyślnie wydrukowane.
Wypróbuj na skrzypcach R.
źródło
*2/6
może prawdopodobnie być/3
?sapply
sposób radzenia sobie z tymi listami! Mogłoby tu być pole do gry w golfa, nie jestem pewien, jak elastyczny jest dozwolony wkład. Jeśli możesz wprowadzić tylko sekwencję współrzędnych, na przykładc(-15.21,0.8,10.1,-0.3,-0.07,23.55)
, możesz zapisać 17 bajtów, zastępując pierwsze wiersze swojej funkcjiy=l[s<-seq(2,sum(1|l),2)];x=l[-s];
. To znaczy ustawieniey
na każdy element z indeksem nieparzystyml
ix
na każdy element z indeksem nieparzystym.matrix(c(-15.21,0.8,10.1,-0.3,-0.07,23.55),2)
jak wtedy, gdy początkiem twojej funkcji może byćx=l[1,];y=l[2,];
, co oszczędza 35 bajtów. (W takim przypadku macierz wejściowa może zostać przetransponowanax=l[,1];y=l[,2];
). Oczywiście najłatwiejszym rozwiązaniem jest, jeśli punktyx
iy
są po prostu wprowadzane jako osobne wektoryfunction(x,y)
, ale nie sądzę, że jest to dozwolone ...c(...)
), A konwersja macierzy musiałaby zostać wykonana wewnątrz funkcji.Python,
156127 bajtówNie golfowany:
Ideone to.
To bierze każdą parę punktów
[x, y]
jako liczbę zespolonąx + y*j
i wysyła wynikowy centroid jako liczbę zespoloną w tym samym formacie.Dla pary punktów
[a, b]
i[c, d]
wartośća*d - b*c
potrzebną dla każdej pary punktów można obliczyć na podstawie wyznacznika macierzyStosując kompleks arytmetyki złożonych wartości
a + b*j
ic + d*j
może być stosowany jakoZauważ, że część urojona jest równoważna wyznacznikowi. Ponadto użycie wartości złożonych pozwala na łatwe zsumowanie punktów w innych operacjach.
źródło
R + sp (46 bajtów)
Zakłada, że
sp
pakiet jest zainstalowany ( https://cran.r-project.org/web/packages/sp/ )Pobiera listę wierzchołków (na przykład
list(c(0.,0.), c(1.,0.), c(1.,1.), c(0.,1.))
)Wykorzystuje fakt, że „labpt” wielokąta jest środkiem ciężkości.
źródło
JavaScript (ES6), 102
Proste wdrożenie formuły
Test
źródło
Python 2, 153 bajty
Nie używa liczb zespolonych.
Wypróbuj online
Nie golfowany:
źródło
Właściwie
454039 bajtówWykorzystuje algorytm podobny do odpowiedzi „Galaretka mil” . Istnieje krótszy sposób obliczania wyznaczników przy użyciu iloczynu kropkowego, ale obecnie występuje błąd z produktem kropkowym Faktycznie nie działa z listami liczb zmiennoprzecinkowych. Sugestie dotyczące gry w golfa mile widziane. Wypróbuj online!
Ungolfing
Krótsza, niekonkurencyjna wersja
To kolejna 24-bajtowa wersja wykorzystująca liczby zespolone. Jest niekonkurencyjny, ponieważ opiera się na poprawkach błędów, które są późniejsze niż to wyzwanie. Wypróbuj online!
Ungolfing
źródło
C ++ 14, 241 bajtów
Wyjście jest strukturą pomocnika
P
,Nie golfowany:
Stosowanie:
źródło
Clojure,
177156143 bajtówAktualizacja: Zamiast wywołania zwrotnego używam
[a b c d 1]
jako funkcji, a argumentem jest tylko lista indeksów tego wektora.1
jest używany jako wartość wartownika podczas obliczaniaA
.Aktualizacja 2: Brak wstępnego obliczania
A
przylet
użyciu,(rest(cycle %))
aby uzyskać przesunięcie wektorów wejściowych o jeden.Orginalna wersja:
Na etapie mniej golfowym:
Tworzy funkcję pomocnika,
F
która implementuje sumowanie z dowolnym wywołaniem zwrotnyml
. DlaA
zwrotów zwrotnych stale1
, natomiast współrzędne X i Y mają swoje własne funkcje.(conj(subvec v 1)(v 0))
upuszcza pierwszy element i dołącza do końca, dzięki czemu łatwo jest śledzićx_i
ix_(i+1)
. Może jest jeszcze kilka powtórzeń do wyeliminowania, zwłaszcza w końcu(map F[...
.źródło