Черепица, заданная конфигурация вершины

11

задача

Задача состоит в том, чтобы выложить мозаику полигонов, учитывая конфигурацию вершины.

счет

Ваша оценка равна «уровню сложности», который достигает ваша заявка. Уровни сложности являются кумулятивными, это означает, что для достижения # 3 вы также должны поддерживать # 1 и # 2.

Представления на одинаковом уровне сложности отличаются количеством байтов; самые низкие победы.

вход

Ввод - это строка, содержащая конфигурацию вершины, представляющую фигуру вершины. То есть список целых чисел, разделенных точками, где каждое целое число (n) представляет собой обычный n-угольник, соединенный общей вершиной.

Должны поддерживаться следующие конфигурации вершин:

  • 3.3.3.3.3.3
  • 3.3.3.3.6
  • 3.3.3.4.4 (обратите внимание, что порядок отражен на рисунке вершины, поэтому нижеследующее действительно отличается)
  • 3.3.4.3.4
  • 3.12.12
  • 3.4.6.4
  • 3.6.3.6
  • 4.4.4.4
  • 4.6.12
  • 4.8.8
  • 6.6.6

Вывод - уровень сложности № 1: рисунок вершины

На этом уровне сложности вывод представляет собой изображение, показывающее фигуру вершины, соответствующую заданному вводу.

К входу добавляется знак, Fчтобы показать, что должна быть выведена фигура вершины, а не полный лист.

Например, F3.6.3.6дает этот рисунок вершины:

3.6.3.6 вершинная фигура

Выход - Уровень сложности № 2: Черепица

На этом уровне сложности выводится изображение, показывающее равномерную мозаику с использованием числа вершин, соответствующего заданному входу.

Например, 3.6.3.6дает этот лист:

3.6.3.6 Черепица

Нет ограничений по цвету или формату (за исключением лазеек).

Выход - Уровень сложности № 3: Двойной тайлинг

На этом уровне сложности «двойная плитка» может быть сформирована из каждой плитки. Это достигается путем рисования линий от центра каждого многоугольника к центру каждого ограничивающего многоугольника.

Двойной лист задается путем добавления ввода с V.

Например, V3.6.3.6это двойная мозаика (красная):

V3.6.3.6 Черепица

JSH
источник
Некоторые из этих фрагментов имеют синонимы. Например, следующие все равно: 3.3.3.4.4 3.3.4.4.3 3.4.4.3.3 4.4.3.3.3 4.3.3.3.4. Должны ли мы поддерживать все синонимы или только лексически низший (как указано в вопросе)? Кроме того, 3.3.3.3.6существует в двух формах зеркального отображения. Я понимаю, что либо приемлемо.
Уровень реки St
Страница, на которую вы ссылаетесь, не соответствует указанному списку. 3.3.3.4.4отсутствует, например. en.wikipedia.org/wiki/… точно соответствует вашему списку. Я понимаю, что контуры или заполненные многоугольники являются приемлемыми (или их комбинация?). Некоторые двойники уже есть в списке. Например 4.4.4.4является его собственным двойным и 3.3.3.3.3.3и 6.6.6являются mutally двойной. Поскольку двойники отображаются независимо от их родителей, я понимаю, что нет необходимости в правильном выравнивании с родителями.
Уровень Река St
вы должны поддерживать ввод, как он отображается в списке - вы можете поддерживать синонимы, но не обязаны - вы должны поддерживать все дуалы, даже самодвойственные.
января
контур / заполнено - хорошо в любом случае. допускается любое оформление, кроме лазеек (все должно быть белым, область рисования крошечной и т. д.). выравнивание не требуется. Я мог бы сказать вам, что вам не разрешено использовать одно отражение, 3.3.3.3.6но как бы вы узнали, что это такое? :)
Jsh
Теперь вы изменили счет, что такое тай-брейк? Это все еще самый короткий код? Если так, конфигурации вершин должны быть разделены точками, или мы можем выбрать другой символ, такой как запятая или пробел?
Уровень Река St

Ответы:

9

BBC BASIC

Ред. 1 Гольф-код, 655 символов ASCII, размер файла токена 614

Некоторые существенные улучшения в таблице данных: хеширование строки A.B..Nдо числа (1*A+2*B+..n*N)+nперед поиском и сохранение только одного вектора перевода (другой генерируется кодом.) Дополнительные пояснения, когда я закончу игру в гольф.

t=PI*2DIMm(9)
c=0z=0INPUTz$
FORi=1TOLEN(z$)d%=VAL(MID$(z$,i))IFd%c+=1m(c)=d%i-=d%=12z+=c*d%
NEXTREPEATREADl,e,f
UNTILl=z+c
l=4-3*(m(3)MOD3=0)-8*(l=59)
DATA69,0,70,65,100,35,66,149,0,49,109,0,52,80,0,55,0,189,39,120,0,44,40,40,58,55,95,47,136,0,59,40,0
VDU23,23,3|
FORr=-9TO19FORs=-9TO9a=1+e*(r*2+s)-f*l*s/4b=1+f*(r*2+s)+e*l*s/4p=40q=0FORk=1TOm(c)/2FORj=1TOc
n=m(j)o=TAN(PI/3)IFe=109ANDn<>4o=1
w=-p*COS(t/n)-q*SIN(t/n)q=p*SIN(t/n)-q*COS(t/n)p=w
u=p:v=q
x=a:y=b
MOVEx,y
FORi=1TO14x+=u*2y+=v*2IFVAL(z$)DRAWx,y ELSEGCOL9LINEx-u-v/o,y-v+u/o,x-u+v/TAN(PI/n),y-v-u/TAN(PI/n)
w=v*COS(t/n)-u*SIN(t/n)u=v*SIN(t/n)+u*COS(t/n)v=w
NEXTNEXT
p=u:q=v
a=x:b=y
NEXTNEXTNEXT

Ред. 0 Гольф-код, 770 символов ASCII, размер файла маркеров 728

Все, что я сделал здесь, это удалил комментарии, ненужные пробелы и кавычки и поместил все в DATAодну строку. Там наверняка есть место для большего количества игры в гольф.

t=PI*2DIMm(9)
c=0INPUTz$
FORi=1TOLEN(z$)d%=VAL(MID$(z$,i))IFd%c+=1:m(c)=d%:i-=d%=12
NEXTREPEATREADl$,e,f,g,h
UNTILMID$(z$,1-(VAL(z$)=0))=l$
DATA3.3.3.3.3.3,240,0,120,70,3.3.3.3.6,200,70,40,210,3.3.3.4.4,80,0,40,150,3.3.4.3.4,-40,150,150,40,3.12.12,300,0,150,260,3.4.6.4,220,0,110,188,3.6.3.6,160,0,80,140,4.4.4.4,80,0,0,80,4.6.12,0,380,330,-190,4.8.8,272,0,136,136,6.6.6,240,0,120,70
VDU23,23,3|
FORr=-9TO19 FORs=0TO9a=1+e*r+g*s
b=1+f*r+h*s
p=40q=0FORk=1TOm(c)/2FORj=1TOc
n=m(j)o=TAN(PI/3):IFe=220ANDn<>4o=1
w=-p*COS(t/n)-q*SIN(t/n)q=p*SIN(t/n)-q*COS(t/n)p=w
u=p:v=q
x=a:y=b
MOVEx,y
FORi=1TO14x+=u*2y+=v*2IFVAL(z$)DRAWx,y ELSEGCOL9LINEx-u-v/o,y-v+u/o,x-u+v/TAN(PI/n),y-v-u/TAN(PI/n)
w=v*COS(t/n)-u*SIN(t/n)u=v*SIN(t/n)+u*COS(t/n)v=w
NEXTNEXT
p=u:q=v
a=x:b=y
NEXTNEXTNEXT

объяснение

Это продолжение моего предыдущего ответа уровня 1, но я решил опубликовать его отдельно, потому что он довольно длинный.

Уровень 2

Это достигается путем перевода моих шаблонов "уровня 1.5" из моего предыдущего ответа. Два вектора трансляции для каждой плитки жестко закодированы. Я использую тот факт, что равнобедренный треугольник с основанием 80 и высотой 70 является очень хорошим приближением равностороннего треугольника, а прямоугольный треугольник с вектором гипотенузы (56,56)имеет длину гипотенузы, очень близкую к 80.

Уровень 3

Чтобы построить дуалы, вместо того, чтобы рисовать ребро многоугольника, мы строим спицу от середины этого ребра до центра многоугольника. Он находится под прямым углом к ​​краю и имеет длину 1/TAN/(PI/n)вектора (u, v), которая, в свою очередь, вдвое меньше длины края.

К сожалению, из-за того, что некоторые полигоны в мозаиках 3.3.3.3.6и 3.4.6.4не нанесены в явном виде, они не будут построены, если мы только сделаем это. Поэтому спица также простирается наружу от многоугольника. Внешнее расширение контролируется переменной o.

По умолчанию расширение является достаточным для достижения центра треугольника, но для 3.4.6.4его необходимо расширить больше, чтобы нарисовать двойные квадраты, которые не отображаются в явном виде. Таким образом, расширение, достаточное для заполнения пропущенных квадратов, применяется, когда шестиугольники и треугольники отображаются явно, но нормальное расширение применяется, когда квадраты отображаются явно, чтобы избежать ложных линий в соседних треугольниках.

Вот как они выглядят без расширений спиц. Отверстия в двойном узоре хорошо видны. Правильный вывод можно увидеть на главной картинке внизу ответа

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

Код комментирования

Отличия от моего предыдущего ответа указаны в строке

  t=PI*2                                          :REM constant Tau = PI*2

  DIMm(9)                                         :REM declare array for the numbers in the input
  c=0                                             :REM number of polygons in the list

  INPUTz$
  FORi=1TOLEN(z$)                                 :REM for each character in the input
    d%=VAL(MID$(z$,i))                            :REM use VAL to return the numeric value of the substring to the right and store to integer variable
    IF d% c+=1 :m(c)=d%: i-=d%=12                 :REM if the last character read was a number, d% contains it, otherwise 0. Advance c and store to m. If it is 12, increment i to skip a character.
  NEXT

  REM BLOCK OF NEW CODE to define vectors (e,f) and (g,h) for each possible tiling

  REPEAT
    READ l$,e,f,g,h                               :REM read an entire line of the data below
  UNTIL MID$(z$,1-(VAL(z$)=0))=l$                 :REM abort the loop when l$ coincides with the input. the MID$ strips off the 'V' from the input where necessary.

  DATA"3.3.3.3.3.3",240,0,120,70
  DATA"3.3.3.3.6",200,70,40,210
  DATA"3.3.3.4.4",80,0,40,150
  DATA"3.3.4.3.4",-40,150,150,40
  DATA"3.12.12",300,0,150,260
  DATA"3.4.6.4",220,0,110,188
  DATA"3.6.3.6",160,0,80,140
  DATA"4.4.4.4",80,0,0,80
  DATA"4.6.12",0,380,330,-190
  DATA"4.8.8",272,0,136,136
  DATA"6.6.6",240,0,120,70

  VDU23,23,3|                                           :REM change linewidth to 3 (default is 1)

  REM END BLOCK OF NEW CODE

  FORr=-9TO19 FORs=0TO9                                 :REM two new loops for translations

      a=1+e*r+g*s                                       :REM modified code for
      b=1+f*r+h*s                                       :REM coordinates to start drawing at


      p=40:q=0                                          :REM vector of first line

      FORk=1TOm(c)/2                                    :REM draw half as many vertex figures as there are sides on the last polygon in the list

        FORj=1TOc                                       :REM for each polygon on the list
          n=m(j)                                        :REM n=number of sides
          o=TAN(PI/3): IF e=220 AND n<>4 o=1            :REM new code for the spoke extension 1/o. 

          w=-p*COS(t/n)-q*SIN(t/n)                      :REM rotate the starting vector anticlockwise by the internal angle of the current polygon
          q=p*SIN(t/n)-q*COS(t/n)                       :REM to avoid overlapping the previous one, if any.
          p=w

          u=p:v=q                                       :REM make a local copy of the vector and coordinates
          x=a:y=b                                       :REM to avoid corruption of p,q,a,b during the drawing of the polygon
          MOVE x,y                                      :REM move the graphics cursor to the start without drawing
          FORi=1TO14                                    :REM do 14 iterations regardless of the number of sides on the polygon
            x+=u*2                                      :REM increment x and y by the vector representing the side
            y+=v*2                                      :REM the value is double (u,v) to facilitate drawing duals later

            REM if z$ begins with a numeric character, draw an edge. If not, change to red and draw a spoke.
            IFVAL(z$) DRAW x,y ELSE GCOL9: LINEx-u-v/o,y-v+u/o,x-u+v/TAN(PI/n),y-v-u/TAN(PI/n)             

            w=v*COS(t/n)-u*SIN(t/n)                     :REM rotate the vector clockwise
            u=v*SIN(t/n)+u*COS(t/n)                     :REM through the external angle of the polygon
            v=w
          NEXT                                          :REM draw next edge of the current polygon
        NEXT                                            :REM draw next polygon of the current vertex

        p=u:q=v                                         :REM once the vertex is finished, we will be two sides around the perimeter of the last polygon.
        a=x:b=y                                         :REM copy the position and direction data into p,q,a,b.
      NEXT                                              :REM draw next vertex figure

    NEXT                                                :REM close the two new translation loops
  NEXT

Выход

Программа выполняет только одну плитку или двойную для каждого запуска. Однако он отображает двойники в красном. Чтобы сэкономить место, я дважды запустил программу, не очищая экран, чтобы наложить двойное поверх обычного тайлинга.

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

Уровень реки St
источник
8

Mathematica

Уровень 1 содержит базовые шаблоны плиток, которые многократно штампуются для создания мозаики плоскости.

Уровень 2 делает плитки.

Есть еще 2 случая, которых я не смог достичь. Похоже, они требуют вращения, а также перевода.

Уровень 1: рисунок вершины (559 байт)

nGon[n_]:=
{ColorData[46,"ColorList"][[n]],Polygon@Switch[n,
3,{{0,0},{-1/2,.866},{-1,0},{0,0}},
4,{{0,0},{0,1},{-1,1},{-1,0},{0,0}},
6,Table[{Cos[i 2Pi/n],Sin[i 2Pi/n]}+{-.5,.866},{i,0,n}],
8,Table[1.31{Cos[i Pi/4],Sin[i Pi/4]}+{-0.5`,1.207},{i,1/2,9}],
_,Table[2{Cos[i 2Pi/n],Sin[i 2Pi/n]}+{-0.5176,1.932},{i,1/2,13}]]}
innerAngle[n_]:=180-360/n
g[{}]=0;
g[a_]:=-(Plus@@innerAngle/@a)

h[{{},__,out_}]:=out
h[{list_,angles_,out_}]:=(
z=GeometricTransformation[nGon[l=list[[1]]],RotationTransform[g[angles] Degree]];
h[{Rest@list,Append[angles,l],Append[out,z]}])

тестирование

Row[Graphics[{EdgeForm[{Blue}], #}, 
      ImageSize -> 70] & @@ {h[{#, {}, {}}]} & /@ {{3, 3, 3, 3, 3, 
    3}, {3, 3, 3, 3, 6}, {3, 3, 3, 4, 4}, {3, 3, 4, 3, 4}, {3, 12, 
    12}, {3, 4, 6, 4}, {3, 6, 3, 6}, {4, 4, 4, 4}, {4, 6, 12}, {4, 8, 
    8}, {6, 6, 6}}]

штампы


Уровень 2: Черепица (690 дополнительных байтов)

Правила возвращают смещения и отступы для каждой конфигурации.

r является основной функцией, которая выводит данные

pпоказывает шаблон и соответствующую плитку. Пробелы соответствуют тем, которые не включены в шаблон.

rules={
{3,6,3,6}-> {2,3.47,0,0},
{4,4,4,4}-> {1,1,0,0},
{6,6,6}-> {3,2.6,1.5,0},
{3,3,3,3,3,3}-> {1.5,1.74,0,.9},
{3,3,3,3,6}-> {2,2.6,-0.4,1.8},

{4,6,12}->{4.2,4.9,0,2.5},
{3,3,4,3,4}-> {1.87,1.86,-.5,-0.5},
{4,8,8}-> {3.4,3.4,0,0},
{3,3,3,4,4}-> {2,1.87,.52,0},
{3,12,12}-> {3.82,6.73,0,0},
{3,4,6,4}-> {1.4,4.3,0(*1.375*)-1,-2.4}};


r[nGons_]:=
Module[{horizHop,vertHop,indent,downIndent},
{horizHop,vertHop,indent,downIndent}=(nGons/.rules);
Graphics[{EdgeForm[{Blue}],Table[GeometricTransformation[h[{#,{},{}}]&/@{nGons},
TranslationTransform[{
If[MemberQ[{{3,3,4,3,4},{3,3,3,3,6},{3,4,6,4}},nGons],indent *row,indent Boole[OddQ[row]]]+col horizHop,
If[MemberQ[{{3,3,4,3,4},{3,3,3,3,6},{3,4,6,4}},nGons],downIndent *col,downIndent Boole[OddQ[col]]]-row vertHop}]],
{col,0,5},{row,0,4}]},ImageSize-> 250]]

p[nGon_]:=Row[{Graphics[{EdgeForm[{Blue}],h[{nGon,{},{}}]},ImageSize->70],r@nGon}];

тестирование

Треугольная черепица

p[{3, 3, 3, 3, 3, 3}]

треугольный


шестиугольный

p[{6, 6, 6}]

шестиугольный


квадрат

p[{4, 4, 4, 4}]

квадрат


неизвестный

p[{3, 3, 4, 3, 4}]

archimedes1


усеченный квадрат

p[{4, 8, 8}]

усеченный квадрат


trihexagonal

p[{3, 6, 3, 6}]

trihexagonal


усеченный шестиугольный

p[{3, 12, 12}]

усеченный шестиугольный


неназванный

p[{3, 3, 3, 3, 6}]

скошенный


удлиненный треугольный

p[{3, 3, 3, 4, 4}]

удлиненный треугольный


Tilings, чтобы выяснить

оставили

DavidC
источник
Я в значительной степени на той же стадии, что и вы. Я могу создавать плитки, но разработка плитки займет немного времени. Вики-стиверилл, размещенный в его комментариях, делает вид, что различные поддерживаемые схемы требуют поддержки. Нужно сделать немного изучения :)
MickyT
Micky, вертикальное и горизонтальное смещение плитки будет зависеть от номера строки, столбца нет. используя смещения, уникальные для рассматриваемого случая. Я работаю над ними один за другим, а потом обобщу.
DavidC
@DavidCarraher отличное начало. Я внес изменения в критерии оценки, которые могут повлиять на вас.
JS
До сих пор хорошо! Если вы уменьшите горизонтальный перевод 3.3.3.3.3.3вдвое, чтобы юниты перекрывались, вы можете избавиться от этих алмазов и исправить эту плитку. У вас еще есть чем заняться 3.3.3.3.6, 3.4.6.4и 4.6.12все же.
Уровень Река St
Re 4.6.12 anyone know what it should look like?- Все необходимые материалы находятся на en.wikipedia.org/wiki/… . Смотрите мой комментарий по этому вопросу. Это страница, отличная от указанной в вопросе. Но 4.6.12также отображается на этой странице в любом случае.
Уровень River St
6

р

Шаг 1

Вот мои усилия по созданию плитки. Черепица, чтобы прийти дальше. Это не проверяет вводимые данные, поэтому инвалиды будут рисовать странные плитки. Ввод набирается после первой строки

i=as.numeric(unlist(strsplit(readline(),"[.]")))
e=c()
for(n in 1:length(i)){
    o=sum(c(0,180-360/i[1:n-1]))
    for(z in 1:i[n]){
        e=c(e,(360/i[n])*(z-1)+o)
    }
}
f=pi/180
plot(c(0,cumsum(sin(e*f))),c(0,cumsum(cos(e*f))),type="l")

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

Шаг № 1, № 2 и № 3: 1898

Наконец-то вернулись к этому. Большая часть этого занимает установка смещений и обработка особых случаев :). Редактировать: V флаг для парных теперь обрабатываются

Общий процесс:

  • Возьмите вход и составьте список
  • Создайте список углов, чтобы нарисовать начальную плитку
  • Вычислить центры каждого многоугольника на плитке и векторы из них, чтобы разделить края
  • Определите нарисованный набор плиток и составьте список угловых смещений. К некоторым плиткам добавлены дополнительные полигоны, чтобы помочь заполнить отверстия.
  • Рисовать плитки
  • Нарисуйте двойники

Я, вероятно, все еще могу играть в гольф немного больше.

##Get input (Enter by itself then type in the tile scheme)
i=strsplit(readline(),"[.]")[[1]]
## Run once i is set
q=0
if(substr(i[1],1,1)=="V"){q=1;i[1]=substr(i[1],2,9)}
i=as.numeric(i)
f=pi/180
e=x=y=q=p=c()
l=length(i)
d=1/(2*tan(pi/3))
g=1/(2*sin(pi/3))
for(n in 1:l){o=sum(c(0,180-360/i[1:n-1]))
r=1/(2*sin(pi/i[n]))
a=o+(180-360/i[n])/2
b=1/(2*tan(pi/i[n]))+d
for(z in 1:i[n]){x=c(x,r*sin(a*f))
y=c(y,r*cos(a*f))
q=c(q,b)
p=c(p,(360/i[n])*(z-1)+o-90)
e=c(e,(360/i[n])*(z-1)+o)}}
if(sum(i)==18&l==6){h=c(60,0);w=c(60,120)}
if(sum(i)==18&l==5){h=c(0,0,60);w=c(60,120,60)
e=c(e,0,-60,60,180,60,180)
x=c(x,g*sin(-30*f),g*sin(-30*f),g*sin(90*f))
y=c(y,1+g*cos(-30*f),1+g*cos(-30*f),1)
q=c(q,d+d,d+d,d+d)
p=c(p,-30,90,-30)}
if(sum(i)==17&l==5&sum(abs(diff(c(i,i[1]),1)))==2){h=c(0,0);w=c(90,60)}
if(sum(i)==17&l==5&sum(abs(diff(c(i,i[1]),1)))==4){h=c(0,30);w=c(270,300)}
if(sum(i)==17&l==4){h=c(0,30,-30);w=c(60,30,90)
e=c(e,150,120,210,300)
x=c(x,sin(150*f)+g*sin(90*f),sin(150*f)+sin(210*f)/2)
y=c(y,cos(150*f)+(1/(2*cos(pi/3)))*cos(90*f),cos(150*f)+cos(210*f)/2)
q=c(q,1,1)
p=c(p,210,120)}
if(sum(i)==18&l==4){h=c(0,0);w=c(120,120)}
if(sum(i)==16&l==4){h=c(0,0);w=c(90,90)}
if(sum(i)==27&l==3){h=c(0,-30,0,30);w=c(60,90,120,150,180)}
if(sum(i)==22&l==3){h=c(0,-30,30,90,60,30)
w=c(90,150,120,90,60,30)
e=c(e,0,-30,-60,30,120,210,30,90,150)
q=q-d+1/(2*tan(pi/4));q[13]=q[17]=q[21]=q[21]+3}
if(sum(i)==20&l==3){h=c(0,-45,-90);w=c(90,0,45)}
if(sum(i)==18&l==3){h=c(0,60,0,-60);w=c(0,60,120,60)}
hx=sum(sin(h*f))
hy=sum(cos(h*f))
wx=sum(sin(w*f))
wy=sum(cos(w*f))
plot(0,0,type="n")
par(pin=c(5,5),usr=c(0,20,0,20))
for(c in -20:20){for(j in -20:20){lines(c((c*hx)+(j*wx)+0,(c*hx)+(j*wx)+cumsum(sin(e*f))),c((c*hy)+(j*wy)+0,(c*hy)+(j*wy)+cumsum(cos(e*f))),type="l")
if(q){for(n in 1:length(x)){lines(c((c*hx)+(j*wx)+x[n],(c*hx)+(j*wx)+x[n]+q[n]*sin(p[n]*f)),c((c*hy)+(j*wy)+y[n],(c*hy)+(j*wy)+y[n]+q[n]*cos(p[n]*f)),col="RED")}}}}

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

MickyT
источник
Ничего себе, только 4 часа позади. И они тоже хорошо выглядят, +1! У вас все дела работают?
Уровень Река St
@steveverrill Спасибо, и это работает для всех случаев в вопросе.
MickyT
4

BBC BASIC

Скачать эмулятор на http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

1-й уровень

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

Уровень 1.5

Уровень 1.5 - это мое собственное обозначение, но это важная веха в моем методе.

Перевод рисунков вершин не всегда приводит к правильному листу. В некоторых случаях строки отсутствуют.

Мое решение этого состоит в том, чтобы обойти самый большой многоугольник, рисуя число вершин для каждой второй вершины этого многоугольника. Это общее решение для всех случаев. Обратите внимание, что у самого большого многоугольника всегда есть четное число сторон, и фигура вершины часто чередуется по часовой стрелке / против часовой стрелки, когда ты идешь вокруг многоугольника. Это может быть наиболее ясно видно с 4.6.12, но это также верно 4.8.8и для 3.12.12: при просмотре с любого конкретного 8-гонового или 12-гоночного чередования вершин являются зеркальным отображением друг друга. Это также то, что происходит, несколько менее очевидно, с 3.3.3.4.4и 3.3.4.3.4: при просмотре с любого конкретного квадрата чередующиеся вершины являются зеркальным отображением друг друга.

Алгоритм, который я использую для перемещения двух сторон вокруг многоугольника, состоит в том, чтобы всегда выполнять 14 итераций цикла рисования ребер, независимо от того, сколько ребер имеет многоугольник. 8 - это коэффициент 16, поэтому при рисовании восьмиугольников графический курсор заканчивается на 16-14 = 2 вершины позади того места, где он начался. У всех 3, 4, 6 и 12 гонов есть стороны, которые имеют множители 12, поэтому графический курсор заканчивается на 14-12 = 2 вершины перед началом.

Цифры можно увидеть ниже. Завтра я надеюсь выработать правильные переводы, чтобы завершить работу. Во всех случаях проводятся достаточные линии для завершения уровня 2 только с переводами. В некоторых случаях рисуется намного больше, чем требуется минимум, но с перекрытием проблем нет: правила ничего не говорят о рисовании линий только один раз :-)

В общем, самый большой полигон является последним в списке. К сожалению, есть один случай, когда это не так: 3.4.6.4поэтому фигура, нарисованная в этом случае, сосредоточена на квадрате, а не на шестиугольнике. Для завершения уровня 2 достаточно линий, используя только переводы, хотя будут определенные квадраты, которые не нарисованы явно. Это создаст некоторые проблемы на уровне 3 (к счастью, я думаю, что знаю, как решить эту проблему.) Точно так же с 3.3.3.3.6достаточным количеством линий для завершения уровня 2, используя только переводы, но будут определенные треугольники, которые не нарисованы явно.

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

Код

Код для уровня 1.5 закомментирован, активирован только код для уровня 1. Есть четыре строки, начинающиеся с REM. Удалите эти REMs, чтобы активировать уровень 1.5.

  t=PI*2                                          :REM constant Tau = PI*2
  DIMm(9)                                         :REM declare array for the numbers in the input
  c=0                                             :REM number of polygons in the list

  INPUTz$
  FORi=1TOLEN(z$)                                 :REM for each character in the input
    d%=VAL(MID$(z$,i))                            :REM use VAL to return the numeric value of the substring to the right and store to integer variable
    IF d% c+=1 :m(c)=d%: i-=d%=12                 :REM if the last character read was a number, d% contains it, otherwise 0. Advance c and store to m. If it is 12, increment i to skip a character.
  NEXT

  FORi=1TOc PRINTm(i),:NEXT                       :REM parsing check for debugging.


  a=601:b=601                                     :REM coordinates to start drawing at
  p=40:q=0                                        :REM vector of first line

  REM FORk=1TOm(c)/2                              :REM draw half as many vertex figures as there are sides on the last polygon in the list

  FORj=1TOc                                       :REM for each polygon on the list
    n=m(j)                                        :REM n=number of sides

    w=-p*COS(t/n)-q*SIN(t/n)                      :REM rotate the starting vector anticlockwise by the internal angle of the current polygon
    q=p*SIN(t/n)-q*COS(t/n)                       :REM to avoid overlapping the previous one, if any.
    p=w

    u=p:v=q                                       :REM make a local copy of the vector and coordinates
    x=a:y=b                                       :REM to avoid corruption of p,q,a,b during the drawing of the polygon
    MOVE x,y                                      :REM move the graphics cursor to the start without drawing
    FORi=1TO14                                    :REM do 14 iterations regardless of the number of sides on the polygon
      x+=u*2                                      :REM increment x and y by the vector representing the side
      y+=v*2                                      :REM the value is double (u,v) to facilitate drawing duals later
      IFVAL(z$) DRAW x,y ELSE LINEx-u,y-v,x-u,y-v :REM if the first character of the input is a number, draw the side of the polygon. The ELSE part is unfinished and will be for drawing duals.
      w=v*COS(t/n)-u*SIN(t/n)                     :REM rotate the vector clockwise
      u=v*SIN(t/n)+u*COS(t/n)                     :REM through the external angle of the polygon
      v=w
    NEXT                                          :REM draw next edge of the current polygon
  NEXT                                            :REM draw next polygon of the current vertex

  REM p=u:q=v                                     :REM once the vertex is finished, we will be two sides around the perimeter of the last polygon.
  REM a=x:b=y                                     :REM copy the position and direction data into p,q,a,b.
  REM NEXT                                        :REM draw next vertex figure

Уровни 2 и 3

Смотрите мой другой ответ.

Уровень реки St
источник