Малювання 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операторами, які переміщують курсор черепахи навколо кута фігури. За один раз він повертає лише один кут. Я стиснув рядки шляхом повторного використання рядків (на зразок psuedo-підпрограм), крім цього, я не перевірив, чи використовую я найкращий шлях. Він виводить у файл постскрипту.

Невелике пояснення коду без гольфу:

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

Імпортує вбудований модуль черепахи та визначає макроси, що вкорочують струни. Модуль черепахи використовує команди для переміщення «черепашки» по екрану (тобто вперед (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(), поки не введіть число, ніж скопіюйте вставити решту. Він призначений для запуску в цілому. Або ви можете скопіювати його у функцію та зателефонувати.

Ось його результати (перетворені з постскрипту):

Примітка: положення цих у вікні змінилося, але загальна їх форма однакова.

тетраедр куб октаедр додекаедр ікосаедр

Це трохи груба сила для кодового гольфу, але я втомився намагатися знайти послідовний малюнок між формами.


Дуже близько. Додекаедр, безумовно, хитріший.
felipa

@Raufio Це дуже приємно. Чи не можливо визначити трикутник (або квадрат або п’ятикутник), а потім просто обернути / перемістити його? Або це ефективно те, що ви зробили?
felipa

Ефективно, так, це я і зробив, але з більшими формами. Наприклад, ікосаед намальований, намалювавши два трикутники, один над іншим, і перемістившись вперед 5 разів, потім скидаючи на нове місце, малюючи алмаз знову, повертаючись назад, повторюючи 5 разів. dце рядок, який робить два трикутники, так це і є(d+'f')*5+setupPosition+(d+'b')*5
Рауфіо

@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

Математика

Поза межами змагань, не вільна мова (якщо тільки безкоштовна пробна версія не вважається безкоштовною)

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

Використання:

f /@ Range@5

Графіка математики


1
Mathematica, безумовно, не є вільною в жодному сенсі. Дуже приємна відповідь, проте.
felipa

@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з правою обертанням та ліній з обертанням лівої руки в одному циклі.

Калормен-перекладач здається менш толерантним до пропущеного пробілу зараз, ніж під час мого першого повідомлення, але код працює на 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

@phase ха-ха, дякую, я насправді роздумував над тим, htщоб приховати це зображення. Я радий, що не став!
Рівень річки Св.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.