Графическое изображение снежинки Коха

13

Генерация снежинки Коха

Снежинка Коха - это треугольник, для nкоторого в середине каждой стороны добавляется еще одна равносторонняя точка: http://en.wikipedia.org/wiki/Koch_snowflake#Properties

Мы уже имели Koch Snowflake вызов для n=4. Новая задача - нарисовать снежинку Коха с любым nмежду 1и 10.

правила

Снежинки не могут быть жестко запрограммированы в программе или в файлах - они должны быть созданы вашей программой.

Ваша программа должна поддерживать все размеры nот 1 до 10.

Количество сторон должно быть введено пользователем через стандартный ввод.

Вы должны распечатать графическое изображение снежинки на экране.

Образцы снежинок Коха с nравными 1, 2, 3 и 4 (зеленые линии только для ясности, не воспроизводите их):

Кох Снежинки

В случае тай-брейка победит программа с наибольшим количеством голосов (поп-конкурс).

Сообщество
источник
Я не понимаю этого: «Вы должны использовать функцию, чтобы вычислить, где разместить пиксель. Если ваша программа не имеет встроенной функции для этой цели, вы можете вычесть стоимость реализации одной из ваших результатов. " Какой пиксель?
xnor
@xnor Изначально он был рассчитан на то, чтобы нарисовать снежинку для каждого пикселя / символа (изначально задача была также ASCII-искусством). Большинство людей, вероятно, будут просто использовать строки, поэтому я уберу это.
Можно ли нарисовать всю заполненную снежинку?
xnor
Конечно. Этот комментарий должен быть длиннее.
Кроме того n=7, вы не можете видеть недавно добавленные треугольники в снежинке на экране компьютера. Все ли "лучшие усилия" здесь хорошо? Существует ли минимальное разрешение для пиксельных решений?
xnor

Ответы:

7

Mathematica 72

Region@Line@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]

п = 3

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

Спасибо за алефальфу.

chyanog
источник
Хорошая работа. Гольф это двумя персонажами, и вы получите победу!
@ Hosch250 Обновлено, спасибо.
chyanog
Вы можете использовать AnglePathв Mathematica 10.1.
алефальфа
@chyaong Graphics@Line@AnglePath[Nest[Join@@({-1,2,-1,#}&/@#)&,{2,2,2},Input[]-1]Pi/3]
alephalpha
1
@alephalpha 73 символа:ListLinePlot@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]
Chyanog
15

MATLAB, 119 115

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

Новые строки не являются частью программы.

x=exp(i*pi/3);
o='~n:~';
P=x.^o;
for l=2:input(o);
P=[kron(P(1:end-1),~~o)+kron(diff(P)/3,[0 1 1+1/x 2]) 1];
end;
plot(P)

n = 9: п = 9

oпроизвольная строка, равная по [0 2 4 0]модулю 6. e iπ / 3, возведенное в эти степени, дает вершины равностороннего треугольника в комплексной плоскости. Первый kronиспользуется для создания копии списка точек, каждый из которых дублируется 4 раза. ~~oэто удобный способ получить вектор из 4 единиц. Во-вторых, diff(P)находит вектор между каждой парой последовательных точек. Кратные этого вектора (0, 1/3, (1 + e -iπ / 3 ) / 3 и 2/3) добавляются к каждой из старых точек.

feersum
источник
Хм, не могли бы вы объяснить подробнее, как работает этот код? Я думал, что знаю немного Matlab, но это ... безумие ?? =)
flawr
@flawr Я добавил несколько заметок, это помогает?
feersum
Большое спасибо! Я запомню этот трюк со злоупотреблением строками =)
flawr
9

T-SQL: 686 (без форматирования)

Для SQL Server 2012+.

Несмотря на то, что это никогда не будет претендентом, мне пришлось посмотреть, смогу ли я сделать это в T-SQL. Ушли на подход, начиная с трех начальных ребер, затем повторяя через каждое ребро и заменяя их четырьмя ребрами для каждого уровня. Наконец, объединяя все это в одну геометрию для уровня, указанного для @i

DECLARE @i INT=8,@ FLOAT=0,@l FLOAT=9;
WITH R AS(
    SELECT sX,sY,eX,eY,@l l,B,1i
    FROM(VALUES(@,@,@l,@,0),(@l,@,@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),-120),(@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),@,@,-240))a(sX,sY,eX,eY,B)
    UNION ALL
    SELECT a.sX,a.sY,a.eX,a.eY,l/3,a.B,i+1
    FROM R 
        CROSS APPLY(VALUES(sX,sY,sX+(eX-sX)/3,sY+(eY-sY)/3,sX+((eX-sX)/3)*2,sY+((eY-sY)/3)*2))x(x1,y1,x2,y2,x3,y3)
        CROSS APPLY(VALUES(x2+((l/3)*SIN(RADIANS(B-210.))),y2+((l/3)*COS(RADIANS(B-210.)))))n(x4,y4)
        CROSS APPLY(VALUES(x1,y1,x2,y2,B),
            (x3,y3,eX,eY,B),
            (x2,y2,x4,y4,B+60),
            (x4,y4,x3,y3,B-60)
        )a(sX,sY,eX,eY,B)
WHERE @i>i)
SELECT Geometry::UnionAggregate(Geometry::Parse(CONCAT('LINESTRING(',sX,' ',sY,',',eX,' ',eY,')')))
FROM R 
WHERE i=@i

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

MickyT
источник
Я понятия не имел, что такое волшебство может быть достигнуто с T-SQL!
Гарри Mustoe-Playfair
9

ЛОГОТИП: 95

to w:c ifelse:c=1[fd 2 lt 60][w:c-1 w:c-1 lt 180 w:c-1 w:c-1]end
to k:c repeat 3[w:c rt 180]end

Определяет функцию kс одним параметром уровня.

редактировать

В этом онлайн-редакторе http://www.calormen.com/jslogo/ вы можете добавить k readwordподсказку для ввода, но по какой-то причине эта команда не поддерживает стандартную аббревиатуру rw.

Решение из 102 символов ниже работает в USBLogo со стандартным вводом, как указано в вопросе. Однако код нуждался в небольших изменениях, поскольку в UCBLogo есть какой-то странный парсер. Это требует toи endдолжно быть в отдельных строках и пространстве, прежде чем :потребуется, но с другой стороны, :являются необязательными.

to w c
ifelse c=1[fd 2 lt 60][w c-1 w c-1 lt 180 w c-1 w c-1]
end
to k c
repeat 3[w c rt 180]
end
k rw
nutki
источник
Как вы запускаете логотип?
бета-распад
@BetaDecay Я использовал это: logo.twentygototen.org, но это было первое, что я нашел: calormen.com/jslogo Вы также можете установить USBLogo
nutki
8

BBC BASIC, 179

REV 1

INPUTn
z=FNt(500,470,0,0,3^n/9)END
DEFFNt(x,y,i,j,a)
LINEx-36*a,y-21*a,x+36*a,y-a*21PLOT85,x,y+a*42IFa FORj=-1TO1FORi=-1TO1z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3)NEXTNEXT
=0

Как и прежде, но в черно-белом, в версиях без гольфа (но обтекаемых) и в гольфе. Не победитель, несмотря на то, что выполнение этого способа избавляет от необходимости специальной обработки для n = 1.

  INPUTn
        REM call function and throw return value away to z
  z=FNt(500,470,0,0,3^n/9)
  END

        REM x,y=centre of triangle. a=scale.
        REM loop variables i,j are only passed in order to make them local, not global.
  DEFFNt(x,y,i,j,a)

        REM first draw a line at the bottom of the triangle. PLOT85 then draws a filled triangle,
        REM using the specified point (top of the triangle) and the last two points visited (those used to draw the line.)
  LINEx-36*a,y-21*a,x+36*a,y-21*a
  PLOT85,x,y+42*a

        REM if the absolute magnitude of a is sufficient to be truthy, recurse to the next level.
        REM j determines if the triangle will be upright, inverted or (if j=0) infinitely small.
        REM i loops through the three triangles of each orientation, from left to right.
  IFa FORj=-1TO1 FORi=-1TO1:z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3):NEXT:NEXT

        REM return 0
  =0

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

REV 0

Согласно ответу ОП на @xnor, заполненные снежинки в порядке. Этот ответ был вдохновлен комментарием xnor. Цвета просто для удовольствия и показать, как они построены. Возьмите треугольник (в данном случае пурпурный) и проложите участок с 6 треугольниками на 1/3 от основания.

  INPUTn
  z=FNt(500,470,n,1,0,0)
  END

  DEFFNt(x,y,n,o,i,a)
  a=3^n/22
  GCOLn
  MOVEx-36*a,y-o*21*a
  MOVEx+36*a,y-o*21*a
  PLOT85,x,y+o*42*a
  IFn>1FORi=-1TO1:z=FNt(x+24*a*i,y+14*a*(i*i*3-2),n-1,-1,i,a):z=FNt(x+24*a*i,y-14*a*(i*i*3-2),n-1,1,i,a)NEXT
  =0

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

Уровень реки St
источник
1
Мне нравится, как это выглядит, как 7 из них слились воедино.
@ hosch250 В самом деле, я, кажется, "изобрел" новый фрактал, силуэт которого оказался снежинкой Коха, и если вы удалите пурпурную часть, у вас останется 6 меньших снежинок Коха. Версия для гольфа будет просто черного силуэта, но я тоже оставлю этот образ.
Уровень Река St
Вы пишете это BBC Basic или BBC BASIC? Я предпочитаю последнее, но я не знаю, правильно ли это ...
Beta Decay
2
@BetaDecay BASIC - это бэкроним для универсального стандартного / символического кода инструкции для начинающих. Бит «Стандарт» является дискуссионным, так как вариантов так много. en.wikipedia.org/wiki/BASIC . Большинство вариантов BASIC предпочитают заглавную версию, но, согласно странице Википедии, Visual Basic предпочитает строчные буквы. Я думаю, что BBC BASIC в том виде, в котором он был отправлен, был заглавным. Я использую версию на bbcbasic.co.uk/bbcwin/bbcwin.html . Это прописные буквы на веб-сайте и в среде IDE, поэтому я бы сказал, что заглавная версия более правильная. Но я не думаю, что это имеет большое значение.
Уровень Река St
Ах, ладно, я продолжу с заглавной версией
Beta Decay
8

Математика - 177

r[x_, y_] := Sequence[x, RotationTransform[π/3, x]@y, y]
Graphics@Polygon@Nest[
 ReplaceList[#, {___, x_, y_, ___}  Sequence[x,r[2 x/3 + y/3, 2 y/3 + x/3], y]
  ] &, {{0, 0}, {.5, √3/2}, {1, 0}, {0, 0}}, Input[]]

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

Бонусный клип с изменением угла наклона средней части

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

рассекать
источник
6

Питон 3 - 139

Использует графическую библиотеку черепах.

from turtle import*
b=int(input())
a=eval(("FR"*3)+".replace('F','FLFRFLF')"*~-b)
for j in a:fd(9/b*("G">j));rt(60*(2-3*("Q">j))*("K"<j))])
Бета распад
источник
Здорово. Мне нравится ваш подход, основанный на строках, - найти фигуру, используя не более двух строк кода! Но вы не можете проверить "G">j, "Q"<jи использовать fd(9/b)для сохранения 3 байта? Кроме того, вы можете избежать ifумножения операторов, например, ("G">j)на аргумент, 9/bи поместить их все в одну строку позади for. Ой! Тогда вы даже можете комбинировать rtи ltиспользовать120*(...)-60*(...)
Falko
Похоже, что для рендеринга снежинки Коха + 1. Ввод 1 должен быть просто треугольником, как показано на рисунке выше.
@Falko Спасибо за всю эту помощь!
бета-распад
@ hosch250 Отредактировано
Beta Decay
Теперь он ничего не рисует, а ввод 1 создает ошибку деления на 0.
4

Python 3, 117 байт

from turtle import*
ht();n=int(input())-1
for c in eval("'101'.join("*n+"'0'*4"+")"*n):rt(60+180*(c<'1'));fd(99/3**n)

Метод:

  • В решении используется графика черепахи Python.
  • n является input - 1
  • Начиная со строки, 0000мы объединяем каждый символ со 101 nвременем итеративно с трюком eval (спасибо @xnor за это).
  • Для каждого символа в последней строке мы поворачиваем на 60 градусов вправо или на 120 градусов влево на основе значения символа ( 1или0 ), а затем перемещаемся вперед на длину ( 99/3^n), которая гарантирует одинаковый размер для всехn .
  • Последний 0в строке будет бесполезен, но он просто перерисовывает ту же строку первым0 .

Пример вывода для input = 3:

Koch

randomra
источник
2

Р: 240 175

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

n=readline();d=c(0,-120,-240);c=1;while(c<n){c=c+1;e=c();for(i in 1:length(d)){e=c(e,d[i],d[i]+60,d[i]-60,d[i])};d=e};f=pi/180;plot(cumsum(sin(d*f)),cumsum(cos(d*f)),type="l")

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

MickyT
источник
2

Мудрый, ты, гвэйв ...

Я знал, что хочу попробовать реализовать это в Befunge-98 с помощью TURT, но я не мог понять, как это сделать, и сидел на нем несколько месяцев. Теперь, совсем недавно, я придумал, как это сделать, не прибегая к самомодификации! И так...

Befunge-98 с отпечатком пальца TURT, 103

;v;"TRUT"4(02-&:0\:0\1P>:3+:4`!*;
>j$;space makes me cry;^
^>1-:01-\:0\:01-\:0
0>I@
^>6a*L
^>ca*R
^>fF

Давайте сначала разберемся с некоторыми деталями реализации:

  • Я протестировал это с помощью CCBI 2.1 , чья реализация TURT (графический отпечаток черепахи) заставляет I«печатать» изображение в файл SVG. Если вы запустите это в CCBI без аргумента- --turt-line=PATHкоманды, по умолчанию он будет выглядеть как файл с именем CCBI_TURT.svg. Это самый близкий к мне «вывести графическое изображение снежинки на экран». с доступными интерпретаторами Funge, которые я смог найти. Возможно, когда-нибудь появится лучший переводчик с графическим дисплеем для черепахи, но сейчас ...
  • В конце должна быть новая строка для CCBI, чтобы он запускался без зависаний (это входит в число символов). Я точно знаю?

По сути, это работает, используя стек как своего рода временную L-систему и расширяя ее на лету. На каждом проходе, если верхний номер в стеке:

  • -2, затем он печатает и останавливается;
  • -1 черепаха поворачивается против часовой стрелки на 60 градусов;
  • 0, он поворачивается по часовой стрелке на 120 градусов;
  • 1, он движется вперед (на 15 пикселей здесь, но вы можете изменить его, изменив fв последней строке);
  • какое-то число n , равное 2 или больше, затем расширяется в стеке до n-1, -1, n-1, 0, n-1, -1, n-1.

Поскольку n = 10этот процесс занимает очень много времени (несколько минут в моей системе), и результирующий SVG имеет размер ~ 10 МБ и не виден при просмотре в браузере, потому что вы не можете отрегулировать размер кисти с помощью TURT. IrfanView работает нормально, если у вас есть нужные плагины. Я не очень знаком с SVG, поэтому я не знаю, какой предпочтительный метод для просмотра этих файлов (особенно, когда они действительно большие).

Эй, по крайней мере, это работает - что, учитывая, что это Befunge, само по себе является чем-то, за что можно быть благодарным.

Kasran
источник
1

Python 2, 127 байт

from turtle import *
def L(l,d=input()-1):
 for x in[1,-2,1,0]:[L(l,d-1),rt(60*x)] if d>0 else fd(l)
for i in'lol':lt(120);L(9)
Dieter
источник
1
Спасибо за то, что 50 000-й пост здесь.
Андрей