Dari Wikipedia :
Centroid dari poligon tertutup yang tidak memotong sendiri didefinisikan oleh n simpul ( x 0 , y 0 ), ( x 1 , y 1 ), ..., ( x n - 1 , y n − 1 ) adalah titik ( C x , C y ), di mana
dan di mana A adalah area yang ditandatangani poligon,
Dalam rumus-rumus ini, simpul diasumsikan diberi nomor sesuai urutan terjadinya sepanjang garis poligon. Lebih jauh, simpul ( x n , y n ) diasumsikan sama dengan ( x 0 , y 0 ), artinya i + 1 pada kasus terakhir harus di-loop ke i = 0 . Perhatikan bahwa jika titik-titiknya diberi nomor searah jarum jam, area A , dihitung seperti di atas, akan memiliki tanda negatif; tetapi koordinat centroid akan benar bahkan dalam kasus ini.
- Diberikan daftar simpul secara berurutan (baik searah jarum jam, atau berlawanan arah jarum jam), cari pusat massa dari poligon tertutup yang tidak memotong sendiri yang diwakili oleh simpul tersebut.
- Jika ini membantu, Anda dapat menganggap input hanya CW, atau hanya CCW. Katakan demikian dalam jawaban Anda jika Anda memerlukan ini.
- Koordinat tidak harus berupa bilangan bulat, dan dapat berisi angka negatif.
- Input akan selalu valid dan mengandung setidaknya tiga simpul.
- Input hanya perlu ditangani yang sesuai dengan tipe data floating point asli bahasa Anda.
- Anda dapat berasumsi bahwa angka input akan selalu mengandung titik desimal.
- Anda dapat mengasumsikan bahwa bilangan bulat input diakhiri dengan
.
atau.0
. - Anda dapat menggunakan angka kompleks untuk input.
- Output harus akurat hingga seperseribu terdekat.
Contohnya
[(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
Lihat juga setiap poligon pada bidang koordinat, tempelkan koordinat tanpa tanda kurung siku di menu "Edit" halaman ini .
Saya mengkonfirmasi hasil saya menggunakan Polygon Centroid Point Calculator ini , yang mengerikan. Saya tidak dapat menemukan satu yang dapat Anda masukkan semua simpul sekaligus, atau yang tidak mencoba menghapus -
tanda Anda saat Anda mengetiknya terlebih dahulu. Saya akan memposting solusi Python saya untuk Anda gunakan setelah orang memiliki kesempatan untuk menjawab.
x
s dany
s menempatkan semua bobot dalam simpul alih-alih didistribusikan ke seluruh tubuh. Yang pertama berhasil karena itu teratur, sehingga kedua metode berakhir di pusat simetri. Yang kedua berfungsi karena untuk segitiga kedua metode mengarah ke titik yang sama.Jawaban:
Jelly ,
2524222118 byteTerapkan rumus yang ditunjukkan dalam masalah.
Disimpan 3 byte dengan bantuan dari @ Jonathan Allan.
Cobalah online! atau Verifikasi semua kasus uji.
Penjelasan
sumber
ṁL‘$ṡ2
denganṙ1ż@
ataużṙ1$
ṙ-ż
untuk menghindari swap dan menyimpan byte lainMathematica, 23 byte
Ambil ITU , Jelly!Sunting: Seseorang tidak hanya mengalahkan Jelly ...
Penjelasan
Hasilkan poligon dengan simpul pada titik yang ditentukan.
Temukan centroid poligon.
sumber
J, 29 byte
Terapkan rumus yang ditunjukkan dalam masalah.
Pemakaian
Penjelasan
sumber
Maxima,
124 118 116 112 112106 byteSaya tidak berpengalaman dengan Maxima, jadi ada petunjuk yang diterima.
Pemakaian:
sumber
Racket 420 byte
Tidak Terkumpul:
Pengujian:
Keluaran:
sumber
R,
129127 byteFungsi tanpa nama yang mengambil R-daftar tupel sebagai input. Setara yang dinamai dapat dipanggil menggunakan mis:
Tidak diikat dan dijelaskan
Langkah terakhir (
c(sum((x+X)*p),sum((y+Y)*p))/sum(p)*2/6
) adalah cara vektor untuk menghitung keduanyaCx
danCy
. Jumlah dalam rumus untukCx
danCy
disimpan dalam vektor dan akibatnya dibagi dengan "jumlahA
"*2/6
. Misalnya:, dan kemudian dicetak secara implisit.
Cobalah R-biola
sumber
*2/6
mungkin bisa/3
?sapply
untuk berurusan dengan daftar itu! Mungkin ada ruang untuk bermain golf di sini, saya tidak yakin seberapa fleksibel input yang diperbolehkan. Jika Anda diizinkan memasukkan hanya urutan koordinat, misalnyac(-15.21,0.8,10.1,-0.3,-0.07,23.55)
, maka Anda dapat menyimpan 17 byte dengan mengganti baris pertama dari fungsi Anday=l[s<-seq(2,sum(1|l),2)];x=l[-s];
. Yaitu, pengaturany
untuk setiap elemen berindeks genapl
, danx
menjadi setiap elemen berindeks ganjil.matrix(c(-15.21,0.8,10.1,-0.3,-0.07,23.55),2)
, saat awal fungsi Andax=l[1,];y=l[2,];
, yang menghemat 35 byte. (Matriks input dapat ditransposisikan, dalam hal inix=l[,1];y=l[,2];
.) Tentu saja, solusi termudah dari semua adalah jikax
dany
titik-titik hanya input sebagai vektor yang terpisahfunction(x,y)
,, tapi saya tidak berpikir itu diperbolehkan ...c(...)
) dan konversi matriks harus dilakukan di dalam fungsi.Python,
156127 byteTidak Terkumpul:
Ide itu.
Ini mengambil setiap pasangan poin
[x, y]
sebagai bilangan kompleksx + y*j
, dan mengeluarkan centroid yang dihasilkan sebagai bilangan kompleks dalam format yang sama.Untuk pasangan poin
[a, b]
dan[c, d]
, nilaia*d - b*c
yang dibutuhkan untuk setiap pasangan poin dapat dihitung dari determinan matriksMenggunakan aritmatika kompleks, nilai
a + b*j
- nilai kompleks danc + d*j
dapat digunakan sebagaiPerhatikan bahwa bagian imajiner setara dengan determinan. Selain itu, menggunakan nilai-nilai kompleks memungkinkan poin untuk dengan mudah dijumlahkan berdasarkan komponen dalam operasi lain.
sumber
R + sp (46 byte)
sp
Paket diasumsikan diinstal ( https://cran.r-project.org/web/packages/sp/ )Mengambil daftar simpul, (misalnya
list(c(0.,0.), c(1.,0.), c(1.,1.), c(0.,1.))
)Mengambil keuntungan dari kenyataan bahwa "labpt" dari suatu Poligon adalah centroid.
sumber
JavaScript (ES6), 102
Implementasi formula yang lurus
Uji
sumber
Python 2, 153 byte
Tidak menggunakan bilangan kompleks.
Cobalah online
Tidak Terkumpul:
sumber
Sebenarnya,
454039 byteIni menggunakan algoritma yang mirip dengan jawaban mil Jelly . Ada cara yang lebih pendek untuk menghitung determinan menggunakan produk titik, tetapi saat ini ada bug dengan produk titik Sebenarnya di mana itu tidak akan bekerja dengan daftar pelampung. Saran golf diterima. Cobalah online!
Tidak melakukanolf
Versi yang lebih pendek dan tidak kompetitif
Ini adalah versi 24-byte lain yang menggunakan bilangan kompleks. Ini tidak kompetitif karena bergantung pada perbaikan bug yang menunda tantangan ini. Cobalah online!
Tidak melakukanolf
sumber
C ++ 14, 241 byte
Output adalah struct pembantu
P
,Tidak Terkumpul:
Pemakaian:
sumber
Clojure,
177156143 bytesPembaruan: Alih-alih panggilan balik yang saya gunakan
[a b c d 1]
sebagai fungsi dan argumennya hanyalah daftar indeks untuk vektor ini.1
digunakan sebagai nilai sentinel saat menghitungA
.Pembaruan 2: Tidak dihitung
A
padalet
, menggunakan(rest(cycle %))
untuk mendapatkan vektor input diimbangi dengan satu.Versi asli:
Pada tahap yang kurang golf:
Menciptakan fungsi pembantu
F
yang mengimplementasikan penjumlahan dengan panggilan balik apa punl
. UntukA
panggilan balik kembali secara konstan1
sedangkan koordinat X dan Y memiliki fungsinya sendiri.(conj(subvec v 1)(v 0))
menjatuhkan elemen pertama dan menambahkan sampai akhir, dengan cara ini mudah untuk melacakx_i
danx_(i+1)
. Mungkin masih ada beberapa pengulangan yang harus dihilangkan, terutama pada akhirnya(map F[...
.sumber