Chuỗi Steiner đệ quy


11

Chuỗi Steiner là một tập hợp N vòng tròn trong đó mỗi vòng tròn tiếp xúc với 2 vòng tròn không giao nhau khác cũng như các vòng tròn trước và vòng tiếp theo của chuỗi, như được thấy trong hình ảnh dưới đây:

Đặt hàng 3 Đặt hàng 5 Đặt hàng 7

Trong thử thách này, bạn sẽ viết một chương trình / hàm rút ra các chuỗi Steiner theo cách đệ quy, nghĩa là các vòng tròn của một chuỗi đã cho sẽ là các vòng tròn cơ sở của một chuỗi lặp khác:

nhập mô tả hình ảnh ở đây

Thử thách

Viết chương trình / hàm chấp nhận kích thước hình ảnh và danh sách các số nguyên biểu thị mức độ của các vòng tròn trong mỗi lần lặp chuỗi liên tiếp và xuất ra hình ảnh với chuỗi Steiner đệ quy được vẽ cho nó.

Đầu vào

Chương trình / hàm của bạn sẽ chấp nhận 2 đối số:

  • s - chiều rộng và chiều cao của hình ảnh
  • ls - danh sách các số nguyên dương biểu thị số lượng vòng tròn có trong mỗi lần lặp liên tiếp của chuỗi, được sắp xếp từ chuỗi cao nhất đến chuỗi dưới cùng nhất

Đầu ra

Chương trình / chức năng của bạn sẽ xuất ra hình ảnh có kích thước sx shiển thị chuỗi Steiner lặp lại.

  • Vòng tròn cơ sở cấp cao nhất sẽ lớn bằng hình ảnh với đường kính s, chính giữa bên trong hình ảnh
  • Để làm cho mọi thứ dễ dàng, 2 vòng tròn cơ sở của chuỗi Steiner sẽ đồng tâm, nghĩa là các điểm trung tâm của 2 vòng tròn cơ sở sẽ giống nhau
  • Cho bán kính ngoài Rvà số vòng tròn trong chuỗi, Ncông thức cho bán kính bên trong R'R' = (R-R*sin(pi/N))/(sin(pi/N)+1)
  • Các vòng tròn của chuỗi cũng như vòng tròn cơ sở bên trong sẽ là các vòng tròn cơ sở bên ngoài của lần lặp tiếp theo của chuỗi
  • Trong khi đệ quy qua các vòng tròn chuỗi, thứ tự của chuỗi tiếp theo sẽ tương ứng với giá trị tiếp theo trong ls
  • Trong khi đệ quy qua vòng tròn bên trong của chuỗi, thứ tự phải giống với thứ tự cha mẹ của chuỗi (ví dụ [5,2]):
  • Đơn hàng 5.2
  • Tất cả các chuỗi nên kết thúc đệ quy ở độ sâu của chiều dài ls
  • Vòng quay của chuỗi không quan trọng:
  • Xoay 1 Xoay 2
  • Tuy nhiên, các phép quay của chuỗi đệ quy so với tâm điểm cha mẹ của chúng phải giống nhau:
  • Đơn hàng 5.2 Đơn hàng không hợp lệ 5.2
  • Tất cả các vòng tròn nên được vẽ bằng một phác thảo hoặc điền rắn
  • Lựa chọn màu sắc được để lại cho việc thực hiện, tiết kiệm cho các sơ hở (ví dụ: lấp đầy mọi thứ với cùng một màu)

Chạy ví dụ

Trong các ví dụ sau, màu sắc được xác định bởi (depth of the recursion)^4.

Bạn có thể tìm nguồn ở đây .

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


Câu trả lời:


4

Javascript ES6, 379 byte

Giải pháp này đã được sử dụng để tạo ra các ví dụ chạy trong câu hỏi.

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

Ung dung:

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

Lưu ý: ftrả về một khung vẽ.

Chạy ví dụ (giả sử có một phần <body>bổ sung):

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

Nên đổ hình ảnh sau vào trang:

Đầu ra

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.