Нарисуй простой куб

10

У нас нет ни одной задачи по рисованию реального 3-мерного куба, так что вот оно:

Вызов

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

вход

Вы вводите 3 отдельных числа от 0 до 359,99 ... Они представляют вращение вокруг осей x, y и z в градусах.

0 0 0
30 0 40
95 320 12

Вывод

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

Редактировать: ASCII также разрешен, чтобы разрешить языки игры в гольф только с текстовым выводом.

Выходные данные для растеризованной или ASCII-графики должны быть не менее 50 * 50 (пиксели для растеризации, символы для ASCII)

Дополнительная информация

Положительная ось z указывает из окна, ось x горизонтальна, а ось y вертикальна. В основном стандарт OpenGL.

Вращения осуществляются против часовой стрелки, если смотреть на куб в отрицательном направлении конкретной оси, например, смотреть вниз по оси y.

Камера должна находиться на оси z на разумном расстоянии от куба в отрицательном направлении z, куб должен находиться в точке (0; 0; 0). . куб также должен быть полностью видимым и занимать не менее 50% рамки рисования. Камера должна смотреть в положительном направлении z на куб.

Вращения куба применяются в порядке x-> y-> z.

Куб вращается вокруг своего центра, он не двигается.

Чтобы спроецировать куб в 2d пространстве, вам необходимо разделить координаты x и y куба на расстояние, параллельное оси z между точкой и камерой.

правила

Библиотеки рендеринга разрешены, но вершины должны быть определены в коде. Нет 3d модели куба класса.

Контрольные примеры

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

Балинт
источник
1
Это должен быть каркас?
Rɪᴋᴇʀ
Хотите включить алгоритм для очков?
Утренняя монахиня
3
В каком порядке / направлениях осуществляется ротация? Куда смотрит камера? Какую проекцию мы должны использовать?
flawr
6
Но, как я уже сказал, повороты не получатся. Как вы уже определили, куб будет перемещен за пределы поля зрения, например, если он будет вращаться вокруг оси x. Пожалуйста, используйте песочницу .
flawr
6
@ EᴀsᴛᴇʀʟʏIʀᴋ google will tell you the formula. Нет , задачи должны содержать как можно больше материалов и информации, необходимых для их решения, включенных в текст сообщения . Я не должен идти в Google или в Википедию, чтобы начать понимать.
кошка

Ответы:

2

Обувь (Рубин) 235 231

Все рассчитано с нуля.

Shoes.app{p,a,b,c=ARGV.map{|j|j.to_f/90}
k=1+i="i".to_c
p=(0..3).map{|j|y,z=(k*i**(j+a)).rect
x,z=(((-1)**j+z*i)*i**b).rect
q=(x+y*i)*i**c
[90*(k+q/(z-4)),90*(k+q/(4+z))]}
4.upto(15){|j|line *(p[j%4][0].rect+p[(j+j/4)%4][1].rect)}}

Звоните из командной строки, например shoes cube3d.rb 0 30 0

Идея состоит в том, чтобы одновременно генерировать / вращать четыре вершины тетраэдра в 3d. Затем, когда они уменьшаются до 2d, мы генерируем четыре вершины обратного тетраэдра (всего 8 вершин, являющихся вершинами куба). Это дает 4 пары вершин, соответствующих четырем диагоналям тела. Наконец, 2d вершины соединяются линиями: каждая вершина исходного тетраэдра должна быть соединена с каждой вершиной обратного тетраэдра, образуя 12 ребер и 4 диагонали тела куба. Заказ гарантирует, что диагонали тела не нанесены на график.

Вывод тестовых случаев

Обратите внимание, что, чтобы соответствовать двум последним тестам, вращение вокруг оси z происходит по часовой стрелке от POV зрителя. Это, кажется, противоречит спецификации. Направление вращения можно изменить, изменив *i**c->/i**c

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

ungolfed

Shoes.app{
  p,a,b,c=ARGV.map{|j|j.to_f/90}   #Throw away first argument (script name) and translate next three to fractions of a right angle.
  k=1+i="i".to_c                   #set up constants i=sqrt(-1) and k=1+i

  p=(0..3).map{|j|                 #build an array p of 4 elements (each element wil be a 2-element array containing the ends of a body diagonal in complex number format)
    y,z=(k*i**(j+a)).rect          #generate 4 sides of square: 1+i,i-1,-1-i,-i+1, rotate about x axis by a, and store in y and z as reals 
    x,z=(((-1)**j+z*i)*i**b).rect  #generate x axis displacements 1,-1,1,-1, rotate x and z about y axis by b, store in x and z as reals
    q=(x+y*i)*i**c                 #rotate x and y about z axis, store result in q as complex number
  [90*(k+q/(z-4)),90*(k+q/(4+z))]} #generate "far" vertex q/(4+z) and "near" vertex q/-(4-z) opposite ends of body diagonal in 2d format.

  4.upto(15){|j|                   #iterate through 12 edges, use rect and + to convert the two complex numbers into a 4 element array for line method
    line *(p[j%4][0].rect+         #cycle through 4 vertices of the "normal" tetrahedron
     p[(j+j/4)%4][1].rect)         #draw to three vertices of the "inverted" tetrahedron. j/4=1,2,3, never 0
  }                                #so the three edges are drawn but the body diagonal is not.
}

Обратите внимание, что по историческим причинам в строке 9 применяется масштабный коэффициент 90 (выбранный таким же, как 90 градусов в строке 2 для игры в гольф), но в итоге не было никакого преимущества в игре в гольф при использовании этого конкретного значения, поэтому он стал произвольный выбор.

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

HTML / CSS / JS, 739 байт, возможно, не конкурирует

Но я просто хотел показать CSS 3D-трансформации.

Нил
источник
Это на самом деле выглядит довольно аккуратно. Я уже сталкивался с преобразованиями CSS3, но у меня были проблемы с этим.
Белинт
Кажется, у вас есть вращения в неправильном порядке. Это должно быть х, то у, то г. У вас есть z, затем y, затем x. @ Bálint может подтвердить.
Уровень Река St
@LevelRiverSt Когда я писал это, я не знал, каким должен быть порядок, и не мог понять его из тестовых случаев, так что спасибо за обновление. Я также переключил направление вращения X, так что теперь я сопоставляю все тестовые случаи.
Нил
Можете ли вы предоставить счетчик байтов? Даже если ответы не являются конкурирующими, у них всегда должен быть счетчик байтов
Downgoat
@ Downgoat Играли в гольф или не играли в гольф?
Нил
0

Клен, 130 + 14 (в процессе)

with(plots):f:=(X,Y,Z)->plot3d(0,x=0..1,y=0..1,style=contour,tickmarks=[0,0,0],labels=["","",""],axes=boxed,orientation=[Z,-X,Y]);

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

Это отображает постоянную функцию внутри блока, затем использует параметры графика, чтобы скрыть метки, метки и саму функцию. Добавление projection=.5к опциям приближает камеру, обеспечивая вид в перспективе.
Я написал это до того, как спецификации были доработаны и порядок ротации x, y', z''вместо x, y, z. Пока я не исправлю углы, вот другое решение

POV-Ray, 182

#include"a.txt"
#include"shapes.inc"
camera{location 9*z look_at 0}
light_source{9*z color 1}
object{Wire_Box(<-2,-2,-2>,<2,2,2>,.01,0)texture{pigment{color rgb 1}}rotate<R.x,-R.y,-R.z>}

читает ввод через a.txtфайл, который должен содержать
#declare R=<xx,yy,zz>;
с xx,yy,zzуглами поворота

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

DenDenDo
источник
1
Yay для использования POV-Ray, это отличная программа. К сожалению, правила сейчас гласят, что нельзя использовать класс 3d-куба.
миль