Звезды из бумаги - большая вещь в моей семье на Рождество, поэтому я подумал, что виртуальная звезда будет крутой.
Ниже приведено изображение обычного додекаэдра (из https://en.wikipedia.org/wiki/Dodecahedron , приписанного упомянутому там автору).
Процесс звездообразования (википедия) применительно к многограннику включает расширение граней до пересечения других граней. Таким образом, начиная с правильного додекаэдра, мы получаем следующие формы:
Маленький звездчатый додекаэдр, Большой додекаэдр и Большой звездчатый додекаэдр
Изображение с http://jwilson.coe.uga.edu/emat6680fa07/thrash/asn1/stellations.html
Это три возможных Звездочки додекаэдра (Вольфрама). Они образуют естественную прогрессию от додекаэдра до маленького звездчатого додекаэдра, большого додекаэдра и большого звездчатого додекаэдра, поскольку мы расширяем грани все дальше и дальше наружу.
задача
Ваша программа или функция должна отображать или выводить в файл изображения один из следующих многогранников: обычный додекаэдр, малый звездчатый додекаэдр, большой додекаэдр или большой звездчатый додекаэдр .
Цветовая схема должна быть как на втором изображении выше. Каждая из шести пар противоположных граней должна быть одного из шести цветов: красного, желтого, зеленого, голубого, синего и пурпурного. Вы можете использовать цвета по умолчанию с этими именами на вашем языке или в его документации или использовать цвета FF0000, FFFF00, 00FF00, 00FFFF, 0000FF и FF00FF (вы можете уменьшить их, уменьшив интенсивность до 75%, если хотите, например, уменьшая F до C.)
Обратите внимание, что мы определяем «лицо» как все области в одной плоскости. Таким образом, на изображениях выше передняя грань желтая (и параллельная задняя грань также будет желтой).
Фон должен быть черным, серым или белым. Края могут быть опущены, но должны быть черными, если они нарисованы.
правила
Ширина отображаемого многогранника должна составлять от 500 до 1000 пикселей (ширина определяется как максимальное расстояние между любыми двумя отображаемыми вершинами.)
Отображаемый многогранник должен быть в перспективной проекции (точка обзора на расстоянии не менее 5 ширины от многогранника) или в ортографической проекции (фактически перспективная проекция с точкой обзора на бесконечности).
Многогранник должен отображаться под любым углом. (Недопустимо выбирать самый простой из возможных углов и создавать жестко заданную 2D-форму.) Угол может быть задан пользователем одним из следующих способов:
Ввод трех углов, соответствующих трем поворотам, от стандартного ввода или в качестве параметров функции или командной строки. Это могут быть либо углы Эйлера (где первое и последнее вращение вокруг одной и той же оси), либо углы Тейта-Брайана (где по одному повороту вокруг оси x, y и z) https://en.wikipedia.org/ wiki / Euler_angles (проще говоря, все происходит до тех пор, пока каждое вращение происходит вокруг оси x, y или z, а последовательные вращения - вокруг перпендикулярных осей.)
Возможность для пользователя поворачивать многогранник с шагом не более 10 градусов относительно осей x и y и обновлять отображение любое произвольное количество раз (при условии, что ось z перпендикулярна экрану).
Многогранник должен быть сплошным, а не каркасным.
Не допускаются встроенные функции для рисования многогранников (я смотрю на тебя, Mathematica!)
счет
Это кодегольф. Самый короткий код в байтах побеждает.
Бонусы
Умножьте ваш счет на 0,5, если вы не используете встроенные функции для 3D-рисования.
Умножьте ваш счет на 0,7, если вы можете отобразить все три звенья додекаэдра, выбираемые пользователем целым числом 1-3, введенным из стандартного ввода, или параметром функции или командной строки.
Если вы выберете оба бонуса, ваш счет будет умножен на 0,5 * 0,7 = 0,35.
Полезная информация (источники как ниже)
https://en.wikipedia.org/wiki/Regular_dodecahedron
https://en.wikipedia.org/wiki/Regular_icosahedron
Додекаэдр имеет 20 вершин. 8 из них образуют вершины куба со следующими декартовыми (x, y, z) координатами:
(± 1, ± 1, ± 1)
Остальные 12 следующие (фи - золотое сечение)
(0, ± 1 / φ, ± φ)
(± 1 / φ, ± φ, 0)
(± φ, 0, ± 1 / φ)
Выпуклая оболочка маленького звездчатого додекаэдра и большого додекаэдра, очевидно, является правильным додекаэдром. Внешние вершины описывают икосаэдр.
Согласно Википедии 12 вершин икосаэдра можно описать аналогично циклическим перестановкам (0, ± 1, ± φ). Внешние вершины малого звездчатого додекагерона и большого додекаэдра (в том же масштабе, что и вышеупомянутый додекаэдр) образуют больший икосаэдр, где координатами вершин являются циклические перестановки (0, ± φ ^ 2, ± φ).
Углы между гранями для додекаэдра и икосаэдра составляют 2 арктана (фи) и арккос (- (√5) / 3) соответственно.
Советы по повороту см. На странице https://en.wikipedia.org/wiki/Rotation_matrix.
РЕДАКТИРОВАТЬ: по ошибке я допустил обычный додекаэдр, и не могу сейчас его отозвать. Бонус х0,7 за рисование всех трех звездчатых многогранников остается. В Новый год я выдам вознаграждение в 100 за ответ, который может отображать большинство из четырех многогранников с кратчайшим кодом в качестве разрыва связи.
источник
dodecahedron
) запрещены. В некоторых языках есть средства для создания 3D-моделей с такими командами, какtriangle[[a,b,c],[p,q,r],[x,y,z]]
. Эти языки обычно имеют встроенные функции для вращения и отображения модели, автоматически заботящиеся о том, чтобы не отображать скрытые лица и т. Д. Решения, подобные этим, разрешены, но не будут привлекать бонус. Цель бонуса - позволить языкам, не имеющим этих возможностей, быть конкурентоспособными, а также привлекать более интересные решения.Polyhedrondata
не допускается, так как он явно является встроенным для рисования многогранников. Если ваш ответ не использует встроенные функции для рисования многогранников и соответствует другим правилам, тогда это приемлемо. Похоже, ваша точка зрения заключается в том, что, учитывая тот факт, что вы должны правильно окрашивать лица,Polyhedrondata
это не сильно вас спасет, поэтому на практике это может быть несколько произвольным ограничением. Я согласен в некоторой степени, но это справедливее для всех, если я не буду менять правила после публикации.Ответы:
Python 2.7, 949 байт
Вот решение для правильного додекаэдра, построенного с использованием matplotlib. Грубый набросок для кода без гольфа (здесь не показан) был обрисован в общих чертах ниже:
источник
Ruby, 784 байта * 0,5 * 0,7 = 274,4
Мой собственный ответ, поэтому не имеет права на мою награду.
Подходит как для не-3D встроенного бонуса, так и для получения бонуса всех звезд.
Ввод в качестве параметров функции
Целое число 0..3, соответствующее правильному додекаэдру, маленький звездчатый додекаэдр, большой звездчатый додекаэдр
Массив из трех целых чисел, соответствующих углам в градусах для поворотов вокруг осей x, y и x (снова) (правильные углы Эйлера, обеспечивающие любое вращение.)
Выведите файл,
p.svg
который можно отобразить в веб-браузере.объяснение
массивы x, y, z внизу кода содержат координаты внешних точек одной грани маленького звездчатого додекаэдра. Это может быть вписано в икосаэдр, 12 вершин которого определяются циклическими перестановками (+/- 377, + / - 233, + / - 0). Обратите внимание, что 377 и 233 являются последовательными числами Фибоначчи, и поэтому 377/233 является превосходным приближением к золотому сечению.
дополнительный массив w содержит координаты x, умноженные на -1, что эквивалентно отражению в плоскости x. Функция f вызывается 6 раз, по одному разу для каждого цвета, с различными циклическими перестановками x, y, z и w, y, z.
Три поворота передаются как параметры в n []. чтобы использовать sin и cos в Ruby, это необходимо сделать
include Math
. чтобы избежать этого, косинус и синус угла получаются путем возведения квадратного корня из -1"i"
в степень (угол в градусах / 90). Действительная и мнимая части этого числа сохраняются в k (косинус) и l ( синус)Перед вращением меняются значения x и y. Затем матричное умножение применяется к значениям y и z, чтобы обеспечить вращение вокруг оси x. Обмен значениями позволяет выполнять три поворота в цикле.
Пока у нас только одно кольцо очков. Чтобы получить остальное, нам нужно найти центр пятиугольника / звезды. Это делается путем нахождения среднего значения координат 5 вершин, которые хранятся в p, q, r.
Как упоминалось ранее, для каждого цвета выполняется только один вызов функции. Знак r (среднее значение координат z и, следовательно, координаты грани) проверяется. Если оно положительное, лицо является передним и, следовательно, видимым. Если оно отрицательное, лицо является задним лицом. Он невидим, и у нас нет вызова функции для противоположного лица. Поэтому все три координаты должны быть инвертированы. Знак r хранится в е, чтобы облегчить это.
Грани построены из 5 треугольников, вершины которых являются линейными комбинациями внешних вершин малого звездчатого додекаэдра и центра грани. В случае малого звездчатого додекаэдра для вершин треугольников мы устанавливаем a = 1 и b = 0 (вклад 1 из x, y, z и 0 из p, q, r). Для 2 базовых вершин треугольника мы устанавливаем c = -0,382 (вклад 1 / золотое отношение ^ 2 из x, y, z) и d = 1,382 (вклад из p, q, r.) Причина отрицательного вклада что базовые вершины треугольника определены в терминах противоположных вершин, которые находятся на противоположной стороне лица. Полученные координаты умножаются на е при необходимости.
Четыре неназванных массива, значения которых назначены для
a,b,c,d
содержания требуемых значений для обычного додекаэдра, малого звездчатого додекаэдра, большого додекаэдра и большого звездчатого додекаэдра, выбранных в соответствии с переменнойt
Обратите внимание, что для маленького звездчатого додекаэдра и большого додекаэдра a + b = c + d = 1. Отношение a + b = c + d применяется к другим фигурам, но применяется другой масштаб.Строка кода SVG создается для каждого треугольника. Он содержит идентификатор, полученный из суммы координат z трех вершин треугольника, описание вершин трех координат треугольника и цвет. обратите внимание, что мы видим прямо вниз по оси z в ортографической проекции. Таким образом, 2D x = 3D x и 2D y = 3D y. Строка добавлена в
h.
наконец, после того, как все вызовы функций завершены, h сортируется таким образом, что треугольники с наибольшим значением z (спереди) отображаются последними, и все это сохраняется в виде файла svg с соответствующим текстом верхнего и нижнего колонтитула.
Неуправляемый в тестовой программе
Вывод
для маленького звездчатого додекаэдра (скоро добавим несколько изображений других полигонов)
1,0,0,0 домашняя позиция
1,30,0,0 повернуть на 30 градусов
1,0,30,0 повернуть вправо на 30 градусов (примечание: для идеального вида сбоку поворот будет
atan(1/golden ratio)
= 31,7 градуса, следовательно, мы все еще можем увидеть небольшой кусочек синего цвета)1,0,20,0 повернуть вправо на 20 градусов
1,60,10, -63 повернуть вниз, вправо и вверх (пример ориентации возможен только при 3 поворотах)
0,30,0,0 обычный додекаэдр
2,0,20,0 великий додекаэдр
3,45,45,45 большой звездчатый додекаэдр
источник
Mathematica,
426424 байтаИспользует встроенный
Graphics3D
для отображения формы. Однако большинство байтов занято сжатыми местоположениями вершин, которые затемPartition
преобразуются в форму, которую можно использоватьPolygon
. В заключение:Обратите внимание, что эту форму можно вращать, нажимая и перетаскивая.
источник