amarao (amarao_san) wrote,
amarao
amarao_san

Category:

Построение на проекции

Поворот куба на 45° в условиях перспективной проекции.

Дан куб в одноточечной перспективе:




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

Сначала мы построим нижнюю сторону куба, то есть "квадрат под углом в 45°.

Начнём с подготовки вспомогательных линий. Так как наш куб будет иметь три грани, видимые зрителю (одна из которых верхняя и нас мало интересует), то мы будем использовать двухточечную перспективу. Построить точки для двухточечной перспективы очень просто - мы строим диагонали на верхней грани кубика и доводим их до линии горизонта, пересечение с горизонтом - точки схождения (points of varnish) для нашего второго (будущего) куба.




(извините за размер, но из перспективы точек не выкинешь, я и так даунсамплю)

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

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

Для экономии точек и линий, мы будем использовать точки схождения верхнего куба для деления прямых на нужные отрезки. В общем случае надо использовать дополнительную точку, но раз у нас уже есть отлично перпендикулярные линии, почему бы не их? Продлеваем пересечение граней вниз (голубые), и проводим по две линии, соединяющие точки схождения с сторонами квадрата на верху нижнего куба (зелёные и оливковые). Кроме того, проводим вторую, вспомогательную, линию (фиолетовая). У нас она параллельна горизонту, но это не обязательно - любая линия, не проходящая через точки схождения, подойдёт:



Обратите внимание, что голубые линии выделяют на фиолетовой равные отрезки для зелёной и оливковой, однако "оливковые" отрезки не равны "зелёным" - так как проекция у нас не центросимметричная.

Теперь у нас простая двухмерная задача (на фиолетовой линии) в обычной декартовой системе координат - надо построить отрезок с центром в "голубой" точке, такой, чтобы его размер относился к длине "зелёного" (и "оливкового") отрезков как будут относиться диагонали квадрата к его его сторонам.

Если не понятно, объясняю: мы спроецировали диагонали, теперь нам надо отметить на этом же отрезке его сторону. Поскольку фиолетовая линия вспомогательная и вся из себя няшно-двухмерно-декартовая, то это архитривиальная задача на построение с помощью циркуля и линейки. Мы можем использовать циркуль, потому что в декартово-няшной двухмерности кружочки круглые (ура!). Делаем построение (нет, мне не интересно, насколько эффективно я это делаю) - поскольку нам надо построить линию в центре, то я построю две полулинии. Для этого я полагаю, что фиолетовая часть это гипотенуза равнобедренного прямоугольного треугольника. Окружности всё готово ('O' в mypaint, кружочки - с зажатым шифтом) - оранжевое построение. Для того, чтобы скопировать точку на вторую половинку - просто построю ещё одну окружность - маджента (розовый).



Повторяем на втором отрезке на фиолетовой прямой ("зелёный" отрезок). Далее - из маджентовых точек проводим по две прямые в точки схождения для нашего будущего куба (куда идут зелёная/оливковая/голубые линии), я их сделал так же красными.



Я думаю, дальшейшее уже понятно. Пересечение красных линий - наше основание (повёрнутый на 45° квадрат), дальше нам надо всего лишь достроить его вверх и провести верхние грани.

Оставшаяся мелкая проблема - поскольку куб у нас имеет грани не на той же z-глубине, как куб снизу, то у нас возникает некоторая проблема с определением его высоты. К счастью, всё просто - мы строим линии, проходящие через точку пересечения квадратов - в этих местах высота кубов будет одинаковая. Дальше нам остаётся провести прямую через вершину этой линии и точки схождения - и высота граней куба становится известной. (жёлтый пунктир, с помощью жёлтого круга превращается в жёлтую линию с точкой сверху, аналогично для "полуоранжевого".



Фиолетовым достраиваем направляющие и подсказку для грани (я чуть-чуть считил и скорректировал ошибку, накопившуюся в процессе отражений линий так, чтобы оба угла были на одной высоте).





Остаётся дорисовать оставшиеся грани и выключить слои с подсказками.



Вот так вот с помощью буханки хлеба и mypaint можно сделать из рисунка чертёж. Дальше я почищу невидимые грани, перерисую в большем разрешении поверх скейлапа, и займусь тенями.

P.S. Да, я понимаю, что тут много халтуры - но я не научился в mypaint точно попадать в место начала линии. Там какие-то глюки и флуктуация +/-2 пиксела (ваком? mypaint?).
Tags: drawing, перспектива
Subscribe

  • systemd-networkd, netlink и arp флуд

    Нереально странный баг пофикшен с помощью eBPF затычки. Для меня большой неожиданностью является реакция на него.…

  • Rust soundness

    Каждый раз, когда я сталкиваюсь с маленькими "но" в Rust'е, это ощущение тщательной продуманности. Например, простейшие fold-функции для итераторов:…

  • still_ntp

    В ходе локального мозгового штурма у меня родилась суперидея. Надо написать ntp сервер, который может отдавать указанную дату. Т.е. сказали при…

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 3 comments