Рисование 3d сетей - Платоновых тел


14

Это базовая версия довольно сложного рисования 3d-сетей - архимедовых тел .

У меня есть слабость к 3d сеткам, которые, будучи вырезанными и сложенными, позволяют вам делать 3d фигуры из бумаги или карты. Задача проста: напишите самую короткую программу, которая может нарисовать сети для 5 тел Платона. На выходе должен быть файл изображения в любом удобном для вас формате (png, jpg и т. Д.).

Все пять фигур описаны на http://en.wikipedia.org/wiki/Platonic_solid . Их сети выглядят так (взято с http://www.newscientist.com/gallery/unfolding-the-earth/2 ).

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

Входные данные: целое число от 1 до 5. Предположим, что фигуры пронумерованы в порядке количества сторон, которые они имеют. Итак, 1 будет тетраэдром, а 5 - икосаэдром.

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

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

Я приму ответ с наименьшим количеством символов ровно через неделю.

Победитель. Только один участник, но это было замечательно. Победитель ... Рауфио за то, что мой любимый кусок кода гольф когда-либо.

Ответы:


8

Питон, 456 429 381

import turtle as t
L="fl"
R="fr"
d=L*3+R*3
b=(d+R)*3
a=[b,120,L*3+"fflflffflflfrflflfffl"+R*4+"flf",90,b+"ffrfrflffrffrfrfrflflf",120,(R*5+L*5+R+L)*5+"rrfr"+L*5+R*2+L*2+R*4+"f",72,(d+"f")*5+"rfl"+((d+"b")*5)[:-1],120]
l=t.lt
f=t.fd
b=t.bk
r=t.rt
p=input()*2-2 
t.setup(.9,.9)
t.goto(-200,150)
t.clear()
for c in a[p]:exec c+"(a[p+1])"
t.getscreen().getcanvas().postscript(file="o")

Я реализовал примитивный интерпретатор с l r f b операторами, которые перемещают курсор черепахи под углом фигур. За один раз получается только один угол. Я сжал строки, повторно используя строки (вроде как псевдо-подпрограммы), кроме этого, я не проверял, использовал ли я лучший путь. Он выводит в файл PostScript.

Небольшое объяснение кода без гольфа:

import turtle as t
Left="fl"
Right="fr"
diamond= Left*3 + Right*3
tetrahedron=(d+R)*3 #used to be b

Импортирует встроенный модуль черепахи и определяет макросы, которые сокращают строки. Модуль Turtle использует команды для перемещения «черепахи» по экрану (т.е. вперед (100), влево (90))

netList=[
   #tetrahedron
   tetrahedron,120,
   #cube
   Left*3+"fflflffflflfrflflfffl"+Right*4+"flf",90,
   #octohedron, builds off the tetrahedron
   tetrahedron+"ffrfrflffrffrfrfrflflf",120,
   #dodecahedron
   (Right*5 + Left*5 + Right + Left)*5
    +"rrfr"+
    Left*5 + Right*2 + Left*2 + Right*4 + "f",72,
   #icosahedron
   (diamond+"f")*5 +"rfl"+((diamond+"b")*5)[:-1],120
]

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

l=t.left
f=t.forward
b=t.back
r=t.right

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

input=int(raw_input())*2-2 
t.setup(.9,.9)
t.goto(-200,150)
t.clear()

Это начинается с ввода (между 1 и 5) и преобразования его в индекс, который указывает на строку формы в списке netList. Эти настройки черепахи, чтобы показать всю сеть. Их можно было бы опустить, если бы задача состояла в том, чтобы просто нарисовать их, но, поскольку нам нужен вывод изображения, они нужны.

for command in netList[input]:
    exec command+"(netList[input+1])"
t.getscreen().getcanvas().postscript(file="o")

Цикл for принимает команды в строке последовательности команд и выполняет их, поэтому для такой строки, как «fl», выполняется «вперед (угол); влево (угол);» вызывая вновь созданные локальные функции. последняя строка выводит файл с именем 'o' в формате постскриптума с использованием функции черепаха.

Для запуска :

Скопируйте его в файл и запустите оттуда. Когда вы запустите его, он будет ждать ввода числа от 1 до 5 (я просто изменил его, чтобы он спрашивал перед настройкой черепахи). Когда вы вводите число, появляется окно и рисует сеть. если вы хотите, чтобы он шел быстрее, вы можете добавить t.speed(200)раньшеsetup .

Вы можете скопировать и вставить его в интерпретатор, но при raw_input()вызове он использует следующую введенную строку "t.setup(.9,.9)"вместо числа. Поэтому, если вы сделаете это, скопируйте до raw_input(), введите число, а затем скопируйте остальные. Он предназначен для запуска в целом. Или вы можете скопировать его в функцию и вызвать его.

Вот его результаты (конвертированные из postscript):

Примечание: их расположение в окне изменилось, но их общая форма одинакова.

тетраэдр куб октаэдр додекаэдр икосаэдр

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


Очень близко. Додекаэдр определенно более хитрый.
Фелипа

@Raufio Это очень мило. Разве невозможно определить треугольник (или квадрат или пятиугольник), а затем просто повернуть / переместить его? Или это действительно то, что вы сделали?
Фелипа

По сути, да, это то, что я сделал, но с большими формами. Например, икосаэдр нарисован, нарисовав два треугольника, один поверх другого, и продвигаясь вперед 5 раз, затем сбрасываясь в новом месте, снова рисуя алмаз, возвращаясь назад, затем повторяя 5 раз. dэто строка, которая делает два треугольника, так что это(d+'f')*5+setupPosition+(d+'b')*5
Raufio

@Raufio Код для игры в гольф не работает для меня. Он открывает окно, которое в основном пустое. Если я затем нажимаю return, я получаю p = (ord (raw_input ()) - 49) * 2 TypeError: ord () ожидал символ, но найдена строка длиной 0
felipa

1
@felipa setup делает окно черепахи достаточно большим, чтобы держать сеть. То же самое goto, он перемещает «черепаху» в -200, 150. clearочищает линию, сделанную goto. Их просто команды для настройки рисования. p=(ord(raw_input())-49)*2принимает число от 1 до 5, соответствующее той форме, которую вы хотите.
Рауфио

6

Mathematica

Вне конкурса, не бесплатный язык (если бесплатная пробная версия не считается бесплатной)

f[n_] := PolyhedronData[ Sort[PolyhedronData["Platonic", {"FaceCount","StandardName"}]][[n,2]],
                                                                                       "NetImage"]

Использование:

f /@ Range@5

Математическая графика


1
Mathematica определенно не свободна в любом смысле. Очень хороший ответ однако.
Фелипа

@felipa это бесплатно, как в пиве на Raspberry Pi.
Shrx

Вы знаете, на этом свободном компьютере малиновый пи
подземный

6

Питон 2 (с Каиром) - 239

from cairo import*
s=PSSurface(None,99,99)
g=Context(s)
g.move_to(30,20)
a=str([34,456,3455,568788,3454445555][input()-1])
f=6.28
for c in a+a[::-1]:exec'g.rel_line_to(8,0);g.rotate(f/int(a[0]));'*int(c);f=-f
g.stroke()
s.write_to_png('o')

Результаты:

Результаты


3

Логотип, 199 байт

TO p:d:n:s
rt :n*45 for[i 1 :n/8][pu setxy :d*:i 0 pd repeat 2[for[k 1 :s*2+2][fd 40 rt (360-720*(:k>:s))/:s] rt 720/:s]]END
TO q:j
apply "p item :j [[70 9 3][56 23 4][70 16 3][105 26 5][40 42 3]]END

Читая это назад, я вижу, что моя оригинальная версия не соответствовала спецификации в том виде, в котором она была написана (взять числовой аргумент и нарисовать одну фигуру), а скорее интерпретировалась другими ответами (нарисовать все фигуры). Новая версия исправляет это. Ожидается, что будет называться, например q 5. csдолжно быть сделано, прежде чем очистить экран и направить черепаху на север.

qвызывает основную функцию pс 3 аргументами. Синтаксис для этого довольно раздутый, поэтому, чтобы побить мой предыдущий счет, мне пришлось сбрить байты в другом месте.

новая версия pпринимает 3 аргумента. Нет необходимости xи yпотому, что мы строим только одну сеть, но dшаг между подразделениями остается. s по-прежнему число сторон на многоугольник, и nтеперь кодирует для двух разных вещей> n/8количество подсчитываемых субъединиц, иn*45 это угол, на который необходимо повернуть черепаху перед запуском (используя естественный мод 360 для вращений. )

Улучшенный цикл завершает рисование s линий с правым поворотом и s+2линий с левым вращением в одном цикле.

интерпретатор calormen кажется менее терпимым к отсутствующим пробелам, чем на момент моего первого поста, но код работает нормально http://turtleacademy.com/playground/en

Логотип, 200 байт

TO p:x:y:d:n:s
for[i 1:n][pu setxy:x:y-:d*:i if:i<>6[pd]repeat 2[repeat:s[fd 40 rt 360/:s]repeat:s+2[fd 40 lt 360/:s]rt 720/:s]]END
p 0 200 40 7 3
p 70 0 80 2 3
p -200 200 105 3 5
rt 45
p 90 90 56 2 4

Переводчик на http://www.calormen.com/jslogo/# Предполагается, что черепаха указывает на север, прежде чем запустить программу. Используйте csкоманду, чтобы очистить экран, наведите черепаху на север и поместите ее в начало координат в центре экрана.

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

Базовая единица всех вышеперечисленных сетей - это пара полигонов. Они расположены в 2 ряда в шахматном порядке, образуя субъединицу из 4 многоугольников, которые можно перевести вертикально, чтобы образовались все сети (кроме октаэдра, который перемещается на чертеже икосаэдра и тетраэдра). Субъединица образует 1 сетку тетраэдра, 1/5 сетки икосаэдра, 1/3 сетки додекаэдра и 2/3 сетки куба (две субъединицы изображены, а два средних квадрата перекрываются).

Код без правил

TO p :x :y :d :n :s                 ;x,y=starting point d=negative vertical offset for each iteration n=#of iterations s=# of sides on polygon
  for[i 1 :n][                      ;iterate n times 
    pu                              ;pen up
    setxy :x :y- :d* :i             ;move pen to start of iteration
    if :i<>6[pd]                    ;pen down (supressed for i=6 to enable part of octahedron to be drawn with icosahedron)
    repeat 2[                       ;draw lower row of 2 polygons, then upper row of 2 polygons
      repeat :s[fd 40 rt 360/ :s]   ;starting at lower left of polygon facing up, draw righthand polygon
      repeat :s+2[fd 40 lt 360/ :s] ;starting at lower right of polygon facing up, draw lefthand polygon, duplicating last two sides
      rt 720/ :s                    ;return turtle to upwards facing in order to draw second row
    ]
  ]
END
cs
p 0 200 40 7 3                      ;draw icosahedron and left side of octahedron (6th iteration is suppressed)
p 70 0 80 2 3                       ;draw right side of octahedron, and tetrahedron
p -200 200 105 3 5                  ;draw dodecahedron
rt 45                               ;turn turtle in preparation for drawing cube
p 90 90 56 2 4                      ;draw cube

@ Фаза, ха-ха, спасибо, я на самом деле подумывал сделать это, htчтобы скрыть это для изображения. Я рад, что я не сделал!
Уровень Река St
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.