Рекурсивні ланцюги Штайнера


11

Ланцюжки Штейнера - це набір з N кіл, де кожне коло є дотичним до двох інших непересічних кіл, а також до попереднього та наступного кіл ланцюга, як видно із зображень нижче:

Замовлення 3 Замовлення 5 Замовлення 7

У цьому виклику ви напишете програму / функцію, яка малює ланцюги Штейнера рекурсивно, тобто кола даного ланцюга будуть базовими колами іншої ітерації ланцюгів:

введіть тут опис зображення

Виклик

Напишіть програму / функцію, яка приймає розміри зображень та список цілих чисел, що позначають рівень кіл у кожній послідовній ітерації ланцюгів, і виведіть зображення із зверненими до нього рекурсивними ланцюгами Штайнера.

Вхідні дані

Ваша програма / функція прийме 2 аргументи:

  • s - ширина та висота зображення
  • ls - список натуральних чисел, що позначають кількість кіл, присутніх у кожній послідовній ітерації ланцюгів, упорядковані від верхньої ланцюга до нижнього самого ланцюга

Вихідні дані

Ваша програма / функція виведе зображення розмірності sx із sвідображенням повторюваного ланцюга Штайнера.

  • Основне коло верхнього рівня буде таким же великим, як зображення діаметром, із sцентром всередині зображення
  • Щоб полегшити ситуацію, 2 базових кола ланцюга Штайнера будуть концентричними, тобто центральні точки двох кіл базової лінії будуть однаковими
  • Враховуючи зовнішній радіус Rта кількість кіл у ланцюзі, Nформула внутрішнього радіуса R'єR' = (R-R*sin(pi/N))/(sin(pi/N)+1)
  • Кола ланцюга, а також внутрішній базовий круг будуть зовнішніми базовими колами наступної ітерації ланцюгів
  • Під час повторної роботи по ланцюгових колах порядок наступного ланцюга повинен відповідати наступному значенню в ls
  • Поки повторюється через внутрішнє коло ланцюга, порядок повинен бути таким самим, як його замовлення батьків (приклад [5,2]):
  • Порядок 5.2
  • Усі ланцюги повинні закінчуватися рекурсією на глибині довжини до ls
  • Обертання ланцюгів не має значення:
  • Обертання 1 Обертання 2
  • Однак обертання рекурсивних ланцюгів щодо центральної точки їх батьків має бути однаковим:
  • Порядок 5.2 Недійсне замовлення 5.2
  • Усі кружечки слід намалювати контуром або суцільною заливкою
  • Вибір кольору залишається на реалізації, окрім лазівки (наприклад, заповнення все тим самим кольором)

Приклад працює

У наступних прикладах колір визначається за (depth of the recursion)^4.

Ви можете знайти джерело тут .

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


Відповіді:


4

Javascript ES6, 379 байт

Це рішення було використано для генерування прикладу прогонів у питанні.

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)}

Безголівки:

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

Примітка: fповертає полотно.

Приклад запуску (передбачається, що <body>слід додати):

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

Потрібно скинути на сторінку таке зображення:

Вихідні дані

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.