Özyinelemeli Steiner Zincirleri


11

Steiner Zincirleri, aşağıdaki dairelerde görüldüğü gibi, her bir dairenin kesişmeyen diğer 2 daireye ve zincirin önceki ve sonraki dairelerine teğet olduğu bir N daire kümesidir:

Sipariş 3 Sipariş 5 Sipariş 7

Bu meydan okumada, Steiner zincirlerini tekrar tekrar çeken bir program / işlev yazacaksınız, yani belirli bir zincirin çevreleri başka bir zincir yinelemesinin temel daireleri olacak:

resim açıklamasını buraya girin

Meydan okuma

Görüntü boyutlarını kabul eden bir program / işlev ve zincirlerin birbirini izleyen her yinelemesindeki dairelerin seviyesini belirten bir tamsayı listesi yazın ve bir görüntüyü kendisine çizilen özyinelemeli Steiner zincirleri ile çıktılayın.

Giriş

Programınız / işleviniz 2 argümanı kabul edecektir:

  • s - görüntünün genişliği ve yüksekliği
  • ls - en üst zincirden en alt zincire kadar sıralanan her ardışık zincir yinelemesinde mevcut olan daire sayısını gösteren pozitif tamsayıların listesi

Çıktı

Programınız / fonksiyonunuz, tekrar eden Steiner zincirini gösteren sx boyutunda bir görüntü verir s.

  • Üst düzey taban çemberi, görüntünün siçinde ortalanmış, çapı olan görüntü kadar büyük olacaktır.
  • İşleri kolaylaştırmak için bir Steiner zincirinin 2 temel dairesi eşmerkezli olacak, yani 2 temel dairenin merkez noktaları aynı olacak
  • Bir dış yarıçapı, göz önüne alındığında R, ve çemberlerin sayısı bir zincirde N, iç yarıçap formülü R'olanR' = (R-R*sin(pi/N))/(sin(pi/N)+1)
  • Zincirin daireleri ve iç taban dairesi, zincirlerin bir sonraki yinelemesinin dış taban daireleri olacaktır
  • Zincir çemberleri boyunca tekrarlanırken, bir sonraki zincirin sırası, ls
  • Bir zincirin iç çemberi boyunca tekrarlanırken, emir ebeveynlerin emriyle aynı olmalıdır (örnek [5,2]):
  • Sipariş 5.2
  • Tüm zincirler, uzunluğun derinliğinde özyinelemeyi sonlandırmalıdır ls
  • Zincirlerin dönmesi önemli değildir:
  • Dönme 1 Dönme 2
  • Bununla birlikte, özyinelemeli zincirlerin ebeveynlerinin merkez noktasına göre dönüşleri aynı olmalıdır:
  • Sipariş 5.2 Geçersiz Sipariş 5.2
  • Tüm daireler bir anahat veya düz dolgu ile çizilmelidir
  • Renk seçimi uygulamaya bırakılır, boşluklar için saklanır (örneğin, her şeyi aynı renkle doldurur)

Örnek İşlemler

Aşağıdaki örneklerde renk ile belirlenir (depth of the recursion)^4.

Burada kaynak bulabilirsiniz .

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


Yanıtlar:


4

Javascript ES6, 379 bayt

Bu çözüm, sorudaki örnek çalışmaları oluşturmak için kullanıldı.

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

Ungolfed:

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

Not: fbir tuval döndürür.

Örnek çalışma ( <body>eklenecek bir varsayar ):

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

Aşağıdaki resmi sayfaya dökmeniz gerekir:

Çıktı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.