nabbla (nabbla1) wrote,
nabbla
nabbla1

Category:

Иногда надо говорить "нет"

Продолжаю мучать свой Monte Carlo Thermal Dynamics - эта хреновина должна посчитать тепловой режим объектива, снаружи покрытого ЭВТИ, внутри покрашенного черной краской, с могучим параболическим зеркалом и сотовой блендой.

Похоже, я близок к цели, базовые фигуры моделируются хорошо и законы термодинамики чтут. Сфера на солнышке разогревается до 5 градусов цельсия (имеется в виду околоземная орбита, 1360 Вт/м2), диск, повернутый к Солнцу нормалью и посеребренный с обратной стороны, разогревается до 120 градусов, цилиндр, повернутый поперек - до 22, а если объекты посадить внутрь зеркальной сферы, то их температуры выравниваются и потерь энергии нет, что не может не радовать.

Но сотовая бленда - это головная боль! Ладно бы сама регулярная ячеистая структура, но ее нужно запихать внутрь цилиндра, грубо обрубив отдельные ячейки, а потом соблюсти тонкий тепловой баланс - если неправильно посчитать площадь поверхности и не сделать равномерного излучения с произвольного участка пластин, последствия катастрофические - закон сохранения энергии еще держится (еще бы ему не держаться, если все передачи энергии идут отдельными квантами, раз излучил - потом обязательно кто-то поглотит), но 2-е начало термодинамики летит в тартарары.

(Щелкните для увеличения, только осторожно, эта штука вызывает глюки)

(на рисунке изображены координаты излученных с бленды фотонов)


У меня каждый объект должен реализовывать ряд методов:
- функция TotalPower - возвращает мощность в ваттах, которая излучается с поверхности объекта
- процедура Radiate - ей передается указатель на "фотон", и он должен случайным образом с объекта излучиться, но, вероятность его излучения с определенной площадки в определенном направлении должна быть пропорциональна силе излучения.
- функция FindCollision - узнать, долбанет ли фотон по объекту и как скоро, не найдется ли объекта ближе по пути следования? Отвечает - будет ли сам факт коллизии и указывает точку и расстояние до нее.
- функция Impact - определяет, поглотится ли фотон в данной точке (если поглотится, поднимаем температуру) или отразится, а если отразится - то по какому закону, можно сделать зеркальное отражение, можно Ламбертовское, а можно произвольную функцию задать.

Ну еще всякое барахло, вроде BoundingSphere (возращает сферу минимального радиуса, внутрь которой умещается объект, это чтобы оценить габариты сцены и сделать "небесную сферу" минимально необходимой), Initialize и Finalize (готовим объекты к работе, сообщаем сколько будет потоков и т.д.).

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

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

Я рвал на себе волосы, был готов взвыть: не хочу это делать, бред какой-то, должно быть простое решение. Сработало даже без "трах-тибидох", простое решение нашлось с мыслью - а что, раньше додуматься никак?

Все что нам нужно - это возможность, что фотон и не излучится вовсе. Сделать Radiate не процедурой, а функцией с булевым возвращаемым значением. Объект честно попытается излучиться фотон, но у него может ничего не получиться и он смиренно вернет false. Поток выполнения пожмет плечами: ну ладно, еще разок попробуем.

Тем самым мы реализуем все тот же старый добрый метод отбраковки, как в задаче с тремя студентами. Найти полную излучаемую мощность - элементарно! Мы возьмем не круглую бленду, а квадратную, с целым числом ячеек, и посчитаем полную площадь, не учитывая толщину стенок. И фотон мы излучим с этой квадратной бленды - и лишь под конец проверим, а он вообще попадает внутрь цилиндра, и не вмуровывается ли в стенку? Если все в порядке, вернем true. Получится, что заявленная нами мощность излучения помножится на вероятность излучения фотона, которую и не нужно считать аналитически - она сама определится по геометрическим соображениям.

Дальше на реализацию квадратной бленды ушло меньше часа, весь старый код отправлен на свалку как непозволительно сложный. Монте-Карло в сочетании с аналитической геометрией - это сила! Осталось ее обуздать.


Красивых картинок программа строить не умеет - я попробовал было, но вероятность, что луч попадет прямиком в камеру - крайне мала! У фотореалистических рейтрейсеров свои законы физики, как у древних: лучи выходят ИЗ ГЛАЗ (из камеры), сканируя все вокруг! Нам это не годится, потому что если мы не смотрим на объект, это еще не значит, что его нет.

Однако, если я не сделаю красивой визуализации, кто же поверит, что у меня рейтрейсер? Так что придется реализовать и такой метод.
Tags: Монте-Карло для чайников, математика, моделирование
Subscribe

Recent Posts from This Journal

  • Огарь крупным планом

    Прям как на пьедестале, гордый такой, здоровенный, песенку спел, потом спустился водички попить, небось горло пересохло. Только на видео я заметил,…

  • Я создал монстра!

    Вот нормальная счастливая пара разъёмов ОНЦ-БС-1-10/14-Р12-2-В и ОНЦ-БС-1-10/14-В1-2-В: У розетки кроме основного выступа, отмечающего "верх",…

  • Нахождение двух самых отдалённых точек

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

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 9 comments