Inilah teka-teki geometri yang menantang untuk Anda!
Diberikan lingkaran A
, dan n
lingkaran lainnya B[n]
, temukan total area yang terkandung di dalamnya A
yang tidak ada di dalam lingkaran B
.
Kode Anda harus sesingkat mungkin.
Memasukkan
Masukan Anda harus berisi informasi berikut:
- Angka floating-point untuk mewakili jari-jari lingkaran
A
. - Daftar angka floating-point untuk mewakili jari-jari lingkaran di
B
. - Daftar pusat lingkaran di
B
. Program Anda mungkin mengharapkan pusat dalam koordinat kutub atau Cartesian. - Secara opsional, Anda dapat menerima jumlah
n
lingkaran di B. Input ini tidak diperlukan.
Harus diasumsikan bahwa pusat lingkaran A
adalah asal, yaitu titik (0, 0)
.
Dijamin tidak ada dua lingkaran B
yang identik, tetapi tidak dijamin bahwa: semua lingkaran B
berpotongan A
, semua pusat B
berada di luar A
, atau tidak ada dua lingkaran yang B
saling berpotongan. Pastikan solusi Anda dapat menangani berbagai kasus tepi.
Anda dapat menerima input dalam urutan apa pun, dan dalam bentuk input teks (melalui stdin atau bahasa Anda yang setara), parameter fungsi, atau argumen baris perintah.
Jika Anda memilih untuk menerima input teks, harus ada satu atau dua karakter pembatas ASCII yang dapat dicetak di antara potongan input.
Keluaran
Program atau fungsi Anda harus menampilkan angka floating-point tunggal yang mewakili area total A
tidak dalam lingkaran mana pun di B
. Jawaban Anda harus akurat untuk setidaknya tiga angka penting untuk semua kasus uji.
Aturan golf-kode umum berlaku.
Solusi Anda tidak harus bergantung pada titik pengambilan sampel dalam lingkaran untuk menentukan area.
Built-in yang secara otomatis menemukan persimpangan lingkaran, menemukan area dalam persimpangan lingkaran, atau menyelesaikan masalah ini segera dilarang.
Uji Kasus
Di setiap gambar, lingkaran A
diuraikan dalam warna biru, dengan lingkaran yang B
diuraikan dalam hijau dan diisi hitam. Area yang harus dikembalikan diisi merah.
(Terima kasih khusus kepada Rainer P. untuk memeriksa solusi saya)
Uji kasus 1:
A = {x: 0, y: 0, rad: 50}
B[0] = {x: 0, y: 0, rad: 100}
Result: 0.00
Uji kasus 2:
A = {x: 0, y: 0, rad: 100.000000}
B[0] = {x: 100.000000, y: 0.000000, rad: 50.000000}
B[1] = {x: 30.901699, y: -95.105652, rad: 50.000000}
B[2] = {x: -80.901699, y: -58.778525, rad: 50.000000}
B[3] = {x: -80.901699, y: 58.778525, rad: 50.000000}
B[4] = {x: 30.901699, y: 95.105652, rad: 50.000000}
Result: 1.3878e+04
Uji kasus 3:
A = {x: 0, y: 0, rad: 138}
B[0] = {x: 100, y: 0, rad: 100}
B[1] = {x: -50, y: -86, rad: 100}
B[2] = {x: -93, y: 135, rad: 50}
Result: 1.8969e+04
Uji kasus 4:
A = {x: 0, y: 0, rad: 121.593585}
B[0] = {x: 81.000000, y: 107.000000, rad: 59.841457}
B[1] = {x: -152.000000, y: -147.000000, rad: 50.000000}
B[2] = {x: 43.000000, y: -127.000000, rad: 105.118980}
B[3] = {x: 0.000000, y: -72.000000, rad: 57.870545}
B[4] = {x: -97.000000, y: -81.000000, rad: 98.488578}
B[5] = {x: -72.000000, y: 116.000000, rad: 66.468037}
B[6] = {x: 2.000000, y: 51.000000, rad: 50.000000}
Result: 1.1264e+04
Uji kasus 5:
A = {x: 0, y: 0, rad: 121.605921}
B[0] = {x: 0.000000, y: -293.000000, rad: 250.000000}
B[1] = {x: 0.000000, y: -56.000000, rad: 78.230429}
B[2] = {x: 0.000000, y: -102.000000, rad: 100.000000}
Result: 2.6742e+04
Bacaan yang disarankan:
Fewell, MP "Area Tumpang tindih Umum Tiga Lingkaran." Oktober 2006. Web. http://dspace.dsto.defence.gov.au/dspace/bitstream/1947/4551/4/DSTO-TN-0722.PR.pdf .
sumber
B
berisi yang lain. Mungkin perlu ditambahkan.1.8970e+04
.B[0] - A intersection: 20653.659515
,B[1] - A intersection: 20757.824115
,B[1] - B[0] intersection: 1841.847766
,B[2] - A intersection: 1289.164541
, yang menghasilkan18969.69009
sebagai jawabannya.Jawaban:
Python 2, 631 byte
Line-break yang didahului oleh
\
adalah untuk membaca mudah, dan tidak dihitung dalam skor.Membaca input melalui STDIN sebagai daftar
(center, radius)
pasangan, di manacenter
ada bilangan kompleks dalam formulirX+Yj
. Lingkaran pertama dalam daftar adalah A (yang pusatnya tidak harus berada di titik asal), dan sisanya dari daftar adalah B . Mencetak hasilnya ke STDOUT.Contoh
Penjelasan
Ini adalah variasi (lebih lama, dan lebih jelek: P) pada solusi saya untuk area Martin Büttner dari tantangan Self-Intersecting Polygon . Ia menggunakan trik yang sama untuk memecah masalah menjadi beberapa bagian yang cukup kecil, yang menjadi lebih mudah dikelola.
Kami menemukan titik-titik persimpangan antara semua pasangan lingkaran (mempertimbangkan A , dan lingkaran di B ), dan melewati garis vertikal melalui masing-masing pasangan. Selain itu, kami melewati semua garis vertikal yang bersinggungan dengan salah satu lingkaran. Kami membuang semua garis yang tidak berpotongan A , sehingga semua garis yang tersisa antara garis singgung kiri dan kanan dari A .
Kami mencari area persimpangan A dan penyatuan lingkaran di B — area merah gelap pada ilustrasi di atas. Ini adalah area yang harus kita kurangi dari A untuk mendapatkan hasilnya.
Di antara setiap pasangan garis vertikal berturut-turut, area ini dapat dipecah menjadi seperangkat trapesium vertikal (atau segitiga, atau segmen garis, sebagai kasing khusus trapesium), dengan segmen busur "berlebih" di sebelah setiap kaki. Fakta bahwa kita melewati garis vertikal sebanyak yang kita lakukan menjamin bahwa area yang dibatasi memang tidak lebih rumit dari itu, karena jika tidak akan ada titik persimpangan tambahan, dan karenanya garis vertikal tambahan, antara dua garis di pertanyaan.
Untuk menemukan trapezoid dan segmen busur ini, untuk setiap pasangan garis vertikal berturut-turut, kami menemukan segmen arc dari masing-masing lingkaran yang terletak di antara kedua garis ini (tentu saja, beberapa lingkaran mungkin tidak memiliki segmen busur antara sepasang garis yang diberikan .) Pada ilustrasi di bawah ini, ini adalah enam segmen busur kuning (terang dan gelap), ketika mempertimbangkan dua garis vertikal merah. Perhatikan bahwa, karena kami meneruskan semua garis vertikal yang bersinggungan ke lingkaran, jika lingkaran memiliki segmen busur di antara dua garis, itu harus memotong kedua garis, yang menyederhanakan sisa algoritma.
Tidak semua busur ini relevan; kita hanya tertarik pada orang-orang yang berada di batas persimpangan antara A dan persatuan B . Untuk menemukan itu, kami mengurutkan busur dari atas ke bawah (perhatikan bahwa busur mungkin tidak saling berpotongan dengan benar, karena ini akan menyiratkan adanya garis vertikal lain antara keduanya yang sedang kami pertimbangkan, sehingga masuk akal untuk berbicara tentang busur sembarang yang berada di atas, atau di bawah, busur lainnya.)
Kami melintasi busur, secara berurutan, sambil tetap menghitung jumlah lingkaran B yang saat ini kami di dalam, n . Jika n berubah dari 0 menjadi 1 saat kita berada di dalam A , atau jika kita berada di busur atas A sementara n adalah nol, maka busur saat ini sesuai dengan satu kaki trapesium. Jika n berubah dari 1 menjadi 0 saat kita berada di dalam A , atau jika kita berada di busur bawah A saat nadalah nol, maka busur saat ini sesuai dengan kaki lain dari trapesium yang sama. Setelah kita menemukan sepasang seperti busur (dua busur kuning cerah dalam ilustrasi di atas), kami menghitung luas yang sesuai trapesium, dan dari dua segmen busur, dan menambahkannya ke daerah total yang harus dikurangkan dari A .
Menghitung area A , serta area trapesium, cukup lurus ke depan. Luas setiap segmen busur adalah luas sektor lingkaran yang sesuai, dikurangi luas segitiga yang simpulnya adalah dua titik akhir segmen busur, dan pusat lingkaran yang sesuai.
sumber