Rantai Steiner Rekursif


11

Rantai Steiner adalah seperangkat lingkaran N di mana setiap lingkaran bersinggungan dengan 2 lingkaran non-berpotongan lainnya serta lingkaran sebelumnya dan berikutnya dari rantai, seperti terlihat pada gambar di bawah:

Memesan 3 Pesan 5 Pesan 7

Dalam tantangan ini, Anda akan menulis sebuah program / fungsi yang menarik rantai Steiner secara rekursif, yaitu lingkaran rantai yang diberikan akan menjadi lingkaran dasar dari iterasi rantai yang lain:

masukkan deskripsi gambar di sini

Tantangan

Tulis program / fungsi yang menerima dimensi gambar dan daftar bilangan bulat yang menunjukkan tingkat lingkaran dalam setiap iterasi rantai yang berurutan, dan hasilkan gambar dengan rantai Steiner rekursif yang digambar padanya.

Memasukkan

Program / fungsi Anda akan menerima 2 argumen:

  • s - Lebar dan tinggi gambar
  • ls - daftar bilangan bulat positif yang menunjukkan jumlah lingkaran yang hadir dalam setiap iterasi rantai yang berurutan, dipesan dari rantai teratas hingga rantai terbawah

Keluaran

Program / fungsi Anda akan menampilkan gambar dimensi sx yang smenampilkan rantai Steiner recusive.

  • Lingkaran dasar tingkat atas akan sebesar gambar dengan diameter s, berpusat di dalam gambar
  • Untuk mempermudah, 2 lingkaran dasar dari rantai Steiner akan konsentris, yaitu, titik pusat dari 2 lingkaran dasar akan sama
  • Diberikan jari-jari luar R,, dan jumlah lingkaran dalam sebuah rantai, Nrumus untuk jari R'- jari dalam adalahR' = (R-R*sin(pi/N))/(sin(pi/N)+1)
  • Lingkaran rantai serta lingkaran dasar bagian dalam akan menjadi lingkaran dasar luar dari iterasi rantai berikutnya
  • Saat berulang melalui lingkaran rantai, urutan rantai berikutnya harus sesuai dengan nilai berikutnya di ls
  • Saat berulang melalui lingkaran dalam rantai, urutannya harus sama dengan urutan orang tuanya (contoh [5,2]):
  • Pemesanan 5.2
  • Semua rantai harus mengakhiri rekursi pada kedalaman panjang ls
  • Rotasi rantai tidak masalah:
  • Rotasi 1 Rotasi 2
  • Namun, rotasi rantai rekursif relatif terhadap titik pusat orang tua mereka harus sama:
  • Pemesanan 5.2 Pesanan Tidak Valid 5.2
  • Semua lingkaran harus digambar dengan garis besar atau isian padat
  • Pilihan warna diserahkan pada implementasi, simpan untuk celah (misalnya, mengisi semuanya dengan warna yang sama)

Contoh Berjalan

Dalam contoh berikut, warna ditentukan oleh (depth of the recursion)^4.

Anda dapat menemukan sumbernya di sini .

chain(600,[5,4,3])

5.4.3

chain(600,[11,1,1,1,1,1,1])

11.1.1.1.1.1.1

chain(600,[5,6,7,8,9])

5.6.7.8.9


Jawaban:


4

Javascript ES6, 379 byte

Solusi ini digunakan untuk menghasilkan contoh berjalan dalam pertanyaan.

f=(s,ls)=>{with(V=document.createElement`canvas`)with(getContext`2d`)with(Math)return(width=height=s,translate(s/=2,s),(S=(o,d=0,n=ls[d],i=(o-o*sin(PI/n))/(sin(PI/n)+1),r=0)=>{fillStyle=`rgba(0,0,0,${pow(d/ls.length,4)})`;beginPath(),arc(0,0,o,-PI,PI),fill();if(d++<ls.length){S(i,d,n);for(;r<n;++r){save();translate(0,(o+i)/2);S((o-i)/2,d);restore();rotate((2*PI)/n);}}})(s),V)}

Tidak Disatukan:

f=(s,ls)=>{                                        // define function that accepts image dimensions and a list of orders
 with(V=document.createElement`canvas`)            // create canvas to draw on, bring its functions into current scope chain
 with(getContext`2d`)                              // bring graphics functions into current scope chain
 with(Math)return(                                 // bring Math functions into current scope chain
  width=height=s,                                  // set width and height of image
  translate(s/=2,s),                               // center the transform on image
   (S=(o,d=0,                                      // define recursive function that accepts outer radius, depth, and optionally order
       n=ls[d],                                    // default chain order to corresponding order in input list
       i=(o-o*sin(PI/n))/(sin(PI/n)+1),            // calculate inner base circle radius
       r=0)=>{                                     // initialize for loop var
    fillStyle=`rgba(0,0,0,${pow(d/ls.length,4)})`; // fill based on depth
    beginPath(),arc(0,0,o,-PI,PI),fill();          // draw circle
    if(d++<ls.length){                             // if within recursion limit
     S(i,d,n);                                     //   recurse on inner circle
     for(;r<n;++r){                                //   loop through all circles of the chain
      save();                                      //   save transform
      translate(0,(o+i)/2);                        //   translate origin to middle of the 2 base circles
      S((o-i)/2,d);                                //   recurse on chain circle
      restore();                                   //   restore transform
      rotate((2*PI)/n);                            //   rotate transform to next circle in chain
   }}})(s),                                        // begin the recursion
 V)}                                               // return the canvas

Catatan: fmengembalikan kanvas.

Contoh menjalankan (mengasumsikan ada <body>untuk menambahkan):

document.body.appendChild(f(600,[13,7,11,5,3]))

Haruskah membuang gambar berikut ke halaman:

Keluaran

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.