-7

4D это 3D

Не понимаю людей которые думают что 4D существует. 4D это всего лишь маркетинговый термин т.е. это тоже самое 3D только с эффектами или же IMax 3D. Ведь существует только 3 измерения насколько я знаю это x y z.

Дубликаты не найдены

+5
Четвёртое измерение невозможно увидеть, как таковое, но для нашего восприятия это время.
раскрыть ветку 4
-1
Вообще 4 измерение создается из 3 мерного изображения https://ru.wikipedia.org/wiki/%D7%E5%F2%FB%F0%B8%F5%EC%E5%F0...
раскрыть ветку 3
-1
Эм... "это абстрактное понятие", видишь ли. Ничто ниоткуда не создается.
-1
А третье из второго, а второе из первого) Я говорю о том, что на бытовом уровне четырёхмерный объект это совокупность всех состояний его трёхмерной проекции. Так же как и трёхмерный объект это совокупность всех состояний его 2d проекций (бесконечное кол-во сечений плоскостью).
-2
4D по дефолту определения это запахи добавляются
+2
Они среди нас - терминаторы, путешествующие во времени!
+1
Припоминаю аттракцион-кабинку :
"12D кино!!!"
раскрыть ветку 3
0
я не представляю как это
раскрыть ветку 2
0
С точки зрения программы, которая обслуживает показ фильмов в этих мульти-D кинотеатрах любой спецэффект - дополнительное измерение.
0
я тоже...
+1
мы не видим четвертого измерения, но многие вещи реально могут иметь свое проявления и в высших измерениях, и то, что мы считаем какой-нибудь качественной характеристикой, может оказаться лишь проекцией свойства высшего порядка.
например, есть материи разной плотности. возможно, их плотность есть скорость внутреннего времени по отношению к нашему стандартному времени. и чем медленнее скорость, тем тверже материал. ведь время для каждой материи тоже может быть разной в четвертом измерении, но мы не можем описать свойство такого порядка.
ИМХО. я могу и бредить)
+1
а как вам такое?)
Иллюстрация к комментарию
0
ты можешь видеть только 3,насколько я знаю...
0
Ну в плане фильмов остальные измерения это запахи, вибрация и прочее. Что бы погружение было как больше глубоким.
0
Фазовое пространство шестимерно, но это наша реальность. Вообще, в теориях струн до 27мерных пространств доходит.
0
я сегодня видел объявление про "4D УЗИ" для беременных
(сопсна это 3D в реальном времени, так что доля правды в этом есть)
Похожие посты
1633

Как становятся учителями.

Этот учебный год — последний.

Я бы, пожалуй, ушёл, но есть нерешённые задачи.

Классное руководство 9 «Б» — в первую очередь.

Родители очень просили, обмануть их ожидания было бы непорядочно с моей стороны.

В следующем году будет только один десятый класс, мы бы расстались в любом случае.


Мне 61 год.

Да, умею пользоваться глобальной сетью, спасибо В. В. Путину за компьютеризацию школы в 2003 году и курсы для учителей.

Нет, информатику я не преподаю, мои дисциплины стары как мир: математика и физика.

Мой рассказ предназначен для тех, кто не понимает, почему тот или иной человек стал учителем средней школы.


Домыслы на этот счёт я слышал и в свой адрес, в том числе и от учеников. Когда 10–12-летний ребёнок говорит, что ты учишь потому, что сам ничего не умеешь — это след «деятельности» взрослых.

В таком возрасте среднестатистический ребёнок до такого не додумается, у него учитель — ещё авторитет.

Старше — возможно.


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

Моя мать — кассир банка, отец — водитель самосвала на угольном разрезе.

Как я учился в школе?

Посредственно.

Двоек не было, особого желания учиться — тоже.

Радостно шёл на три предмета: труд, физкультура и история.


Кем хотел стать?


В те годы, по моде в нашем городе — шахтёром, но родители настаивали на десятилетке.

В старших классах я подтягивался 22 раза.

Драться не умел, но ко мне не лезли.

В 16 лет у меня стремительно упало зрение по невыясненным тогда причинам.

Про шахту пришлось забыть.

Мой друг, почти отличник, поехал в Москву поступать в Менделеевский. Поехал я с ним скорее для компании, нежели для поступления.


Не поступил, конечно.

Сидеть без дела тогда было как-то не принято, и я пошёл по заводам устраиваться на работу.

Начал по алфавиту, на первом же заводе меня приняли.


Авторемонтный.


Ничегошеньки я не умел.

На первых порах доверяли мне только двигатель на блоках дёрнуть, потом втянулся.

Изучал по ночам устройство двигателя по картинкам, днём пытался сопоставить это с грязной, запылённой и замасленной грудой запчастей.


Напарнику я был абсолютно безразличен. «Смотри сам, там всё видно», — его любимая фраза.

А вот бригадир…

Тогда я впервые задумался о роли учителя.

Через три месяца я сам перебрал двигатель.

Я был счастлив и горд.

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

С тех пор я взял в привычку всегда учиться, а заодно не пить пиво и водку. К концу моего первого года работы я получал 250–270 рублей.

Сказочные деньги для восемнадцатилетнего парня.


Армия прошла мимо.

Клеймо «не годен».

Я ревел в голос прямо в военкомате.

Мою авантюру с закапыванием атропина в глаза разоблачили, я был наивен.

Я умолял окулиста, но…


Я остался на заводе.

На целых пять лет, как потом выяснилось.

Зарабатывал уже около 300 рублей, тратить деньги мне было совершенно некуда, и я стал ездить по выходным на экскурсии в областной центр и в Москву.

Музеи, театры — оказалось, что это бывает интересно.

Из цеха меня перевели в опытно-исследовательскую бригаду.

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


Поступил заочно в автодорожный институт.

Нас таких было двенадцать человек на заводе.

Одну сессию мы проводили в Москве, на вторую преподаватели приезжали к нам.

«Мы рабочие люди, нам некогда».

Так рассуждал наш старший, никто ему не перечил.

На нашу местную сессию мы скидывались по четвертному.

Кто-то из преподавателей был принципиален, кто-то ставил зачёты просто так, а кто-то и брал подношения.

А однажды…


Ей было лет 30–35.

Преподавала она то ли метрологию, то ли госстандарты.

Старший подошёл ко мне и сказал, что нам всё поставят, только надо ей организовать «культурную программу».

Дальше старший замялся и что-то мямлил про то, что они все семейные и только я холостой.

Мне выделили сто рублей денег, ЗИС-110 с путевым листом на «обкатку», модный широкий галстук, пачку известных резиновых изделий.

Товарищи подготовили баню и комнату на загородном полигоне.

Я справился.

На «отлично».


Психанул я через неделю.

Бросил ненужный институт и решил, что смогу не допустить такого «образования», если лично пойду учить.

Почему физмат?

Потому что учителя математики больше других предметников работают с детьми.

Год я готовился.

Было очень тяжело, но мотивация творит чудеса.

Это я запомнил.


Нет, самостоятельно дойти до всего в алгебре — проблематично.

Мне помогала соседка, инженер химкомбината.

Я пробовал обратиться к своим школьным учителям, но в ответ было многозначительное «мы же тебе говорили».

Это я тоже запомнил и никогда не злорадствую и не афиширую неудачи и прозрения своих учеников.


Я поступил.

Учился хорошо, на последнем курсе отказался от аспирантуры — хотел учить, а не философствовать на эту тему.

Мой родной город меня не дождался: за время учёбы я познакомился иногородней девушкой, женился.

После выпуска уехал работать по месту жительства жены.


К тому времени она родила ребёнка.

Моя первая зарплата — 114 рублей, сравните с моими доходами на заводе. Впрочем, лично для меня оказалось, что не в деньгах счастье.

В чём?


Уклонюсь от ответа на этот вопрос, это глубоко личное.

Нет единого счастья, единой цели в жизни и единого мерила успеха.

Люди разные, и это правильно.

Главное — оставаться человеком.

Не пошла алгебра — да бог с ней!

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


Молодец.

В большинстве профессий алгебра не нужна, но ты был честным, ты боец, где-нибудь ты пробьёшься и станешь уважаемым человеком.

Сколько их таких было только среди моих выпускников!

Бизнесмены, чиновники, артисты и просто хорошие люди.


Но есть другие.

Это они покупают «решебники», просят срочной помощи на контрольной через интернет.

Это они прикрывают свою лень ненужностью предмета, они ставят учителю вопрос: «А ты сам кто такой?» 

У них нет проблем, им папа всё купит.

Они готовы жаловаться, доставать справки, врать, скандалить и провоцировать.

Неприятно это видеть у десятилетнего ребёнка.

К сожалению, родителей в большинстве случаев всё устраивает.


Без помощи родителей учитель почти бессилен.

Вот и формируется мина замедленного действия.

Эти дети тоже вырастают в бизнесменов, чиновников и т. д., но есть разница.

Они с детства плевали на интересы государства, они с детства привыкли обожать только себя.

Пусть живут, ничего с этим не сделаешь, однако противно.


Честность, исполнительность, трудолюбие — эти идеалы я старался привить на своих занятиях.


Научить быть человеком.

Предметы?

Да, конечно, и предметы.

Может быть, немного не с тем акцентом.

Что такое геометрия?

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

Прямые, треугольники и прочие пирамиды — это шелуха.


Что такое физика?

Это развитие критического рационального мышления.

Верить в науку, признавать свои заблуждения.

Для общего развития иметь представление о природе, чтобы не вдаваться в дремучую мистику.

Расчёт тангенциального ускорения — это на любителя или на будущего инженера.


Что такое алгебра?

Это развитие абстрактного мышления.

Больше ничего, остальное — шелуха.

Вот так как-то и получалось.

Было здорово, но хватит.

Устал, возраст, здоровье, моральная опустошённость.


Зря ли я прожил жизнь?

Я считаю, не зря, но каждый из вас имеет право на свою точку зрения.

Показать полностью
427

Женщина, которая изобрела общую алгебру

Женщина, которая изобрела общую алгебру Физика, Общая алгебра, Эмми Нётер, Наука, Женщина, Алгебра, Длиннопост

Математик Эмми Нётер была гением, положившим начало новому подходу в физике.


Теорема Нётер в теоретической физике – то же самое, что и естественный отбор в биологии. Если бы вы написали уравнение, которое кратко излагает все, что мы знаем о теоретической физике, то на одном его конце были бы имена Фейнмана, Шрёдингера, Максвелла и Дирака. Но если вы напишите фамилию Нётер с другой стороны уравнения, то это бы компенсировало их всех.

Женщина, которая изобрела общую алгебру Физика, Общая алгебра, Эмми Нётер, Наука, Женщина, Алгебра, Длиннопост

Эмми Нётер родилась в Баварии в 1882 году. Она посещала школу-пансион и получила диплом, дающий право преподавать языки - французский и английский. Однако вскоре девушка поняла, что математика, которой занимались ее отец и брат в Эрлангенском университете, интересует ее куда больше. Женщинам не разрешалось поступать в высшие учебные заведения, но Эмми сдала вступительный экзамен на пять с плюсом и просто посещала лекции вольнослушательницей до тех пор, пока университет не стал принимать девушек на обучение. И Нётер смогла получить степень доктора наук.


Девушка начала заниматься исследовательской работой и, можно сказать, изобрела общую алгебру. Эта дисциплина изучает алгебраические системы (алгебраические структуры) и редуцировать их до максимально абстрактных форм. Целью Нётер было понять, как математические идеи коррелируют друг с другом и построить общие математические структуры. Она никогда не заявляла о том, что открыла нечто революционное, но её работа стала новым подходом в математике.


Пока Нётер писала свою принципиально новую работу в Эрлангенском университете, у неё не было ни должности, ни зарплаты. Единственное, что она могла – время от времени заменять своего отца на лекциях по математике, когда он был болен.

Спустя семь лет математики Давид Гильберт и Феликс Клейн пригласили Нётер поработать с ними в Гёттингенском университете. Они хотели, чтобы женщина решила проблему сохранения энергии в теории общей относительности Эйнштейна. Пытаясь сделать это, Эмми сформулировала теорему Нётер, тем самым внеся один из самых значительных вкладов в теоретическую физику.


Эйнштейн говорил о теореме как о примере «прозорливого математического мышления». При этом теорема имеет простую формулировку: каждой непрерывной симметрии физической системы соответствует некоторый закон сохранения. Под симметрией подразумевается, что физический процесс — или его математическое описание — остается неизменным при изменении какого-либо аспекта установки.


Например, идеальный маятник, который бесконечно долго колеблется туда-сюда, симметричен во времени. Исходя из теоремы Нётер, все, обладающее временной симметрией, сохраняет энергию. Таким образом, маятник не теряет энергии. Если же система обладает вращательной симметрией — то есть работает одинаково вне заивимости от ориентации в пространстве — то в ней сохраняется момент импульса. Это означает, что если объект вначале вращается, то он продолжит вращаться бесконечно долго. Стабильность, которую мы видим у орбит планет, – это следствие симметрий, которые работают вместе — сохранение и энергии, и углового момента тел.


Теорема Нётер позволяет нам провести глубокие связи между результатами экспериментов и фундаментальным математическим описанием их физики. Размышления о физике в этом случае формируют основу того типа теоретического скачка, который привел физиков к теоретическому предсказанию бозона Хиггса задолго до того, как частицу смогли обнаружить в результате исследований на БАК. Симметрия настолько фундаментальна для физики, что стандартная модель физики частиц часто называется по её группам симметрии: U(1)×SU(2)×SU(3).


Это, конечно, здорово, что Нётер произвела коренной переворот в физике — но при этом она продолжала работать без зарплаты, часто читая лекции за Гильберта и будучи его ассистенткой. В 1922 году, спустя 4 года после публикации своей теоремы, женщина получила статус внештатного доцента, и ей начали давать неболоьшую зарплату. Эмми читала лекции по всей Европе.


Когда нацисты пришли к власти, Нётер оказалась без работы, потому что она была еврейкой. Ей пришлось эмигрировать в Америку, где она стала приглашенным профессором в женском колледже в Брин-Море. Кроме того, Эмми Нётер читала еженедельные лекции в Принстоне. В Брин-Море Нётер впервые стала работать с женщинами-математиками. Трагично, что ей было отведено всего лишь 2 года, чтобы этим наслаждаться. Нётер умерла в 1935 году в возрасте 53 лет после неудачной операции по удалению раковой опухоли.


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


Даже сегодня в математике и физике мы можем наблюдать асимметрию в отношении к ученым женского и мужского пола (это называется «Эффектом Матильды в науке»). Как Нётер и говорила — как только симметрия нарушается, что-то теряется.


Источник: The woman who invented abstract algebra

Перевод: Екатерина Шутова (SciOne)

Показать полностью 1
174

Рисуем в 3d на c++ поверхность, заданную формулой

Всем привет, меня зовут TaHk и по ночам я программирую на c++.

Недавно я столкнулся с задачей (не столько про c++, сколько математической), решение которой показалось мне красивым, и я хочу им поделиться.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

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


Итак. Задача -- нарисовать в 3d поверхность, которая задана не набором полигонов, а формулой.

Алгоритм был выбран следующий:

0. Исходные данные.

*Координаты нулевой точки поверхности (точка в глобальной системе координат, являющаяся центром координат для формулы, которой задана поверхность);

*Вектор нормали поверхности в нулевой точке (показывает, как наклонена поверхность относительно глобальных координат);

*Размеры поверхности по x, y и z (чтобы она просчитывалась не по бесконечность во все стороны, а в рамках определенного объема);

*Координаты "глаза";

*Вектор направления взгляда;

*Вектор, показывающий, где у "глаза" верх;

1. Формируем лучи из каждого пикселя экрана и проверяем на пересечение с поверхностью.

2. Если луч не пересекается с поверхностью -- окрашиваем пиксель в черный.

3. Если пересекается -- определяем освещенность точки. Для этого определяем нормаль к поверхности плоскости, и чем меньше угол между нормалью и лучом из камеры -- тем ярче точка.


Давайте разбираться с каждой задачей в отдельности.

1. Лучи из каждого пикселя экрана.

Ну, тут все просто. Чтобы задать луч -- нужна точка и вектор. Точка у нас есть -- это координаты "глаза". И направление взгляда есть. Соответственно, луч для координат [0,0] у нас уже есть. Что же делать с остальными координатами? Ответ на этот вопрос даст (или нет) эта картинка:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Для начала, нам нужны единичные векторы dx и dy, перпендикулярные друг другу и вектору взгляда, чтобы построить на них плоскую систему координат, которая будет для нас экраном. Вектор dy у нас уже есть («Вектор, показывающий, где у "глаза" верх» в исходных данных). Что же на счет dx? А тут приходит на помощь векторная алгебра, из которой мы помним (или нет), что результатом векторного произведения двух векторов является вектор, перпендикулярный векторам-множителям, с нормой равной площади параллелограмма, построенного на этих векторах. Соответственно, если исходные векторы перпендикулярны друг другу и оба с длиной равной единице – длина результата тоже будет равен единице. А это прекрасно, ведь нам нужен именно единичный вектор.

Таким образом,

dX[0] = tv[1]*dY[2] - tv[2]*dY[1];
dX[1] = tv[2]*dY[0] - tv[0]*dY[2];
dX[2] = tv[0]*dY[1] - tv[1]*dY[0];

где tv — вектор направления взгляда, а dY вектор, показывающий где у взгляда верх.

Дальше, было бы неплохо определиться с длиной векторов dx и dy, определив таким образом размер экрана (по сути, это управление углом обзора). Мне оптимальным показался вариант, когда у экрана размер равен единице

dX[0] /= max_x;
dX[1] /= max_x;
dX[2] /= max_x;
dY[0] /= max_x;
dY[1] /= max_x;
dY[2] /= max_x;

Где max_x – разрешение экрана по x. Да, dy тоже делится на max_x, чтобы длина вектора dx была равна вектору dy, так как иначе изображение будет растянуто по одной из осей.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Итак, у нас есть:

dX, dY – векторы, определяющие плоскость экрана.

dZ – вектор направления взгляда.

for (int y = 0; y <= max_y; ++y) {
for (int x = 0; x <= max_x; ++x) {
tv[0] = dZ[0]+x*dX[0]+y*dY[0];
tv[1] = dZ[1]+x*dX[1]+y*dY[1];
tv[2] = dZ[2]+x*dX[2]+y*dY[2];
// tv – вектор, показывающий направление луча из точки [x,y] экрана
// ...
};
};

В рамках этого цикла мы и будем работать дальше.


2. Пересечение луча с поверхностью.

Обычно лучший способ найти в пространстве точку пересечения луча с поверхностью, которая задана формулой – это решить систему уравнений, состоящую из уравнения плоскости и уравнения луча. Но если в уравнение плоскости проникает тригонометрия – решений становится бесконечное множество (буквально бесконечное, вида x = 0 ± 2πn, где n∈R ), и что делать программно с этой бесконечностью – не ясно. Поэтому мы будем искать точку пересечения итеративно:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

1. Определяем параллелепипед, ограничивающий нашу поверхность (мы помним, что по условиям ограничили ее в размерах).

2. Ищем точки пересечения луча и параллелепипеда. Получаем 2 точки – «вход» и «выход» в пределы параллелепипеда.

3. В точке «входа» переводим координаты из глобальной системы координат в локальную для параллелепипеда.

4. В локальных x и у находим по формуле поверхности координату z. Если найденная координата z больше, чем у точки «входа», фиксируем, что мы «под» поверхностью. Иначе – фиксируем, что мы «над» поверхностью.

5. От точки «входа» до «выхода» проверяем аналогичным образом все точки на луче с заданным шагом. Как только на следующем шаге состояние отличается от того, что было на предыдущем – значит, нашли точку пересечения.

6. Если до точки «выхода» состояние не менялось – значит пересечения не было.


Теперь по пунктам.

Существует простой и понятный алгоритм быстрого поиска пересечения прямоугольника с лучом на плоскости. Для его понимания нужно ввести пару терминов:

Точка входа – точка пересечения луча с прямой, в случае если нормаль этой прямой направлена навстречу лучу.

Точка выхода – точка пересечения луча с прямой, в случае если нормаль этой прямой направлена навстречу лучу.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Алгоритм такой:

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

К чему это я? А вот к чему. Этот подход отлично работает и в пространстве, если заменить 4 прямые на 6 плоскостей.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Как мы помним, поверхность задана точкой и нормалью и ограничена в размерах по x, y и z. Причем эти x y и z – в локальных координатах. То есть наш параллелепипед, ограничивающий поверхность, должен уметь вращаться вместе с поверхностью.

Поэтому для начала определим эти плоскости с учетом поворота параллелепипеда с поверхностью. Для этого нам понадобятся 3 вектора:

ddX[3] = {0,0,0}; // единичный вектор, который направлен вдоль оси X нашей поверхности
ddY[3] = {0,0,0}; // единичный вектор, который направлен вдоль оси Y нашей поверхности
ddZ[3] = {0,0,0}; // единичный вектор, который направлен вдоль оси Z нашей поверхности

с ddZ все понятно – это нормаль к поверхности.

С ddX и ddY сложнее. Одной только точкой и нормалью можно задать в пространстве только бесконечную поверхность. А тут нам нужно зафиксировать поворот этой плоскости вокруг оси z. Это можно сделать разными способами – я беру еще одну точку на плоскости и фиксирую ее координаты в глобальной системе координат. Допустим, это точка point2, а нулевая точка поверхности — point. Тогда

ddX[0] = point2[0] - point[0];
ddX[1] = point2[1] - point[1];
ddX[2] = point2[2] - point[2];
len = sqrt(ddX[0]*ddX[0]+ddX[1]*ddX[1]+ddX[2] *ddX[2]) ;
ddX[0]/=len;
ddX[1]/=len;
ddX[2]/=len;

Как мы видим, я не забыл, что нам нужен именно единичный вектор (с длиной равной единице), поэтому я посчитал длину вектора от точки point к точке point2 и разделил каждую координату на длину. Эта процедура называется нормализация вектора – приведение его к единичной длине с сохранением направления.

Ну и ddY по старой схеме (как в пункте 1, где мы экран рисовали) определяем как векторное произведение ddX на ddZ:

ddY[0] = ddX[1]*ddZ[2] - ddX[2]*ddZ[1];
ddY[1] = ddX[2]*ddZ[0] - ddX[0]*ddZ[2];
ddY[2] = ddX[0]*ddZ[1] - ddX[1]*ddZ[0];

Таким образом, мы можем задать все 6 плоскостей. Например, плоскость, ограничивающая параллелепипед «снизу» определяется так:

spoint[0] = point[0] - z * ddZ[0];
spoint[1] = point[1] - z * ddZ[1];
spoint[2] = point[2] - z * ddZ[2];
n[0] = -ddZ[0];
n[1] = -ddZ[1];
n[2] = -ddZ[2];

где point — нулевая точка нашей поверхности, а z - половина высоты параллелепипеда.

Остальные – по аналогии, меняем только - на + и буквы координат.


Дальше нужно в общем виде понимать, как мы будем искать точки пересечения луча и плоскости. Допустим, плоскость задана точкой point[3] и нормалью n[3]. Луч задан точкой tp[3] и вектором tv[3]. Еще одна картинка в стиле «я у мамы paint master»:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Несложно догадаться, что если векторы n и tv имеют единичную длину, то расстояние от точки tp до точки пересечения с плоскостью будет равно -h/p. Шучу, сложно догадаться. Но при желании вы можете это проверить. Даже так – если вы сейчас в школе проходите векторную алгебру – вы должны это проверить и выложить в комментариях доказательство. Иначе вам поставят двойку. Или что там сейчас ставят в школах…

Как же найти эти h и p? Тут на помощь снова приходят определения из векторной алгебры. Скалярное произведение векторов численно равно длине проекции одного из этих векторов на другой. Как определить скалярное произведение? А примерно так:

float MulVecSc(float *Vec1, float *Vec2){
return Vec1[0]*Vec2[0] + Vec1[1]*Vec2[1] + Vec1[2]*Vec2[2];
};

Как мы видим из рисунка, h – это проекция на нормаль вектора от точки tp до точки point, принадлежащей плоскости, а p – это проекция на нормаль вектора tv.

vp[0] = point[0] - tp[0];
vp[1] = point[1] - tp[1];
vp[2] = point[2] - tp[2];
p = MulVecSc(n,tv);
h = MulVecSc(n,vp);
t = - h/p;

Знак p покажет нам, с какой стороны плоскости мы находимся (а значит покажет, нашли мы точку «входа» или «выхода»).


Резюмируем. В пространстве точки пересечения луча с параллелепипедом находятся так:

float ddY[3] = {point2[0],point2[1],point2[2]};
float ddX[3] = {0,0,0};
float ddZ[3] = {n[0],n[1],n[2]};
tmMulVec(n,ddY,ddX);
// 6 плоскостей. Ищем самый поздний "вход" и самый ранний "выход"
// Плоскость 1
spoint[0] = point[0] + x * ddX[0];
spoint[1] = point[1] + x * ddX[1];
spoint[2] = point[2] + x * ddX[2];
vp[0] = tp[0]-spoint[0];
vp[1] = tp[1]-spoint[1];
vp[2] = tp[2]-spoint[2];
n[0] = ddX[0];
n[1] = ddX[1];
n[2] = ddX[2];
p = tmMulVecSc(lv_n,tv);
t = - tmMulVecSc(lv_n,lv_vp)/p;
if(p>0.0f){ // выход
if(t<t_out)
t_out = t;
}else{ // вход
if(t>t_in)
t_in = t;
};
// Плоскость 2
spoint[0] = point[0] - x * ddX[0];
spoint[1] = point[1] - x * ddX[1];
spoint[2] = point[2] - x * ddX[2];
vp[0] = tp[0]-spoint[0];
vp[1] = tp[1]-spoint[1];
vp[2] = tp[2]-spoint[2];
n[0] = -ddX[0];
n[1] = -ddX[1];
n[2] = -ddX[2];
p = tmMulVecSc(lv_n,tv);
t = - tmMulVecSc(lv_n,lv_vp)/p;
if(p>0.0f){ // выход
if(t<t_out)
t_out = t;
}else{ // вход
if(t>t_in)
t_in = t;
};
// Плоскость 3
// ...
// Плоскость 4
// …
// Плоскость 5
// …
// Плоскость 6
// ...
if(t_in<t_out&&t_out>0){
// есть пересечение
};
Так. Теперь мы знаем, что в промежутке от t_in до t_out мы внутри параллелепипеда.
Дальше, как и планировали, будем проверять каждую точку с неким шагом h на то, находится она выше или ниже поверхности в локальных координатах.
Что такое локальные координаты?
Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Это система координат, образованная теми самыми ddX, ddY, ddZ которые мы определили выше. Как очевидно из рисунка (на этот раз действительно очевидно), если у нас есть точка p, то вектор, ведущий от нулевой точки нашей поверхности до точки p будет определяться векторной суммой x*ddX+y*ddY+z*ddZ, где x y и z локальные координаты этой точки. Что ж, в таком случае, зная глобальные координаты точки p мы можем получить локальные таким образом:

vtp[0] = p[0]-point[0];
vtp[1] = p[1]-point[1];
vtp[2] = p[2]-point[2];
x = MulVecSc(ddX,vtp);
y = MulVecSc(ddY,vtp);
z = MulVecSc(ddZ,vtp);

Дальше, проверяем, находимся мы в этой точке под поверхностью или над.

F = F_xy; // тут у нас определение значения функции, описывающей плоскость. Его мы рассмотрим позже, в 3й части.
if(z<F){ // определяем, находимся мы в точке входа «над» или «под» поверхностью
in = true;
}else{
in = false;
};

Дальше – просто делаем это в цикле, перемещая точку p:

for(t = t_in+h;t<=t_out;t+=h){
pt[0] = tp[0] + tv[0]*t;
pt[1] = tp[1] + tv[1]*t;
pt[2] = tp[2] + tv[2]*t;
vtp[0] = point[0]-pt[0];
vtp[1] = point[1]-pt[1];
vtp[2] = point[2]-pt[2];
x = -tmMulVecSc(ddX,vtp);
y = -tmMulVecSc(ddY,vtp);
z = -tmMulVecSc(ddZ,vtp);
F = F_xy;
if(z<F){ // сейчас внутри
if(!in){ // были снаружи
break;
};// были снаружи
}else{ // сейчас снаружи
if(in){ //были внутри
break;
};//были внутри
}; // внутри/снаружи
}; // for t_in ... t_out
if(t>=t_out){
break; // никакого пересечения не было
};
// на данный момент t – это расстояние от точки tp до точки пересечения
// фактически точка на расстоянии t уже после пересечения с плоскостью, поэтому
// в качестве точки пересечения берем t-h
t-=h
collision_pt[0] = tp[0] + tv[0]*t;
collision_pt[1] = tp[1] + tv[1]*t;
collision_pt[2] = tp[2] + tv[2]*t;

Вот мы и нашли, где луч пересек поверхность. Запихнув это решение в цикл, который мы получили в первой части, мы получим картинку, на которой будут видны очертания поверхности. Но на 3d картинку это не будет похоже – чтобы одна точка поверхности отличалась от другой (что создаст объем) нужно определить освещенность.


3. Определение освещенности точки.

В рамках этой задачи мы не будем заморачиваться с источниками света – будем считать, что у нас один источник и он расположен непосредственно за «глазом». В таком случае расчет освещенности сводится к простому определению нормали к поверхности. Чем меньше значение проекции – тем темнее точка, так как свет падает под большим углом. Поскольку векторы у нас единичные, значение проекции будет изменяться в диапазоне [0..1], что позволяет просто домножать значение цвета на проекцию и получать нужную картинку.

Итак, вернемся к «простому определению нормали».

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Пора наконец определиться с тем, какую поверхность мы рисуем. В коде ранее была конструкция F = F_x; Тут F_x это макрос, в который я подставляю формулу, которую хочу рисовать. Разумеется, в последствии в код можно будет подставить любую формулу, но для примера нужно взять что-то конкретное. Я выбрал такое:

#define F_xy cos((x*x+y*y)/20.0)/(1+(x*x+y*y)/100.0)

Чтобы понимать, что мы хотим увидеть в программе, построим этот график в каком-нибудь инструменте, который это уже умеет:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Так как же определить нормаль в какой-нибудь точке поверхности? Нормаль – это вектор перпендикулярный касательной плоскости к поверхности в заданной точке, правильно? А коэффициент угла наклона касательной к графику функции в точке – это ни что иное как производная функции в этой точке. Таким образом, нужно просто взять с обратным знаком производные исходной функции по трем координатам – это и будет вектор нормали.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Для примера возьмем двумерный график:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

(графики касательных смещены для наглядности)

Функция Y=x^2. Её производная Y'=2x. Соответственно, в точке X=0.5 коэффициент угла наклона равен единице, а в точке 2 – четырем. Из графика видно, что коэффициент угла наклона с обратным знаком показывает угол наклона линии, перпендикулярной касательной. Эта же логика работает и для более сложных графиков. Так же она работает и в пространстве.

Поэтому запишем уравнение поверхности в виде cos((x*x+y*y)/20.0)/(1+(x*x+y*y)/100.0) - z = 0 и возьмем производные по трем координатам:

F'x = ((sin((x*x+y*y)/20.0)*x/10.0)*(1+(x*x+y*y)/100.0)-(x/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))

F'y = ((sin((x*x+y*y)/20.0)*y/10.0)*(1+(x*x+y*y)/100.0)-(y/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))

F'z = -1

Вернемся к коду. Теперь зная точку пересечения и ее локальные координаты – мы можем найти нормаль. Она будет определяться как N[3] = {-F'x,-F'y,-F'z}. Но нужно помнить, что это ее значения в локальных координатах. Чтобы перевести в глобальные – нужно каждый компонент умножить на значение вектора той оси, которой он соответствует:

#define F_x ((sin((x*x+y*y)/20.0)*x/10.0)*(1+(x*x+y*y)/100.0)-(x/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))
#define F_y ((sin((x*x+y*y)/20.0)*y/10.0)*(1+(x*x+y*y)/100.0)-(y/50.0)*cos((x*x+y*y)/20.0))/((1+(x*x+y*y)/100.0)*(1+(x*x+y*y)/100.0))
#define F_z 1.0
float Fx = F_x;
float Fy = F_y;
float Fz = F_z;
collision_normal[0] = ddX[0]*Fx+ddY[0]*Fy+ddZ[0]*Fz;
collision_normal[1] = ddX[1]*Fx+ddY[1]*Fy+ddZ[1]*Fz;
collision_normal[2] = ddX[2]*Fx+ddY[2]*Fy+ddZ[2]*Fz;

Теперь мы готовы определять компоненты цвета в заданной точке. Допустим, базовый цвет поверхности у нас лежит в переменной rgb:

Shade = 255.0f * MulVecSc(collision_normal,tv);
if(Shade < 0)
Shade = -Shade;
r = Shade * rgb[0];
g = Shade * rgb[1];
b = Shade * rgb[2];

Оценим результат:

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Сменим формулы:

#define F_xy 0.3*(sin(x)*cos(y/2.0)+cos(x/2.5)*sin(y/1.5))
#define F_x -0.3*(cos(x)*cos(y/2.0)-sin(x/2.5)*sin(y/1.5))
#define F_y -0.3*(-sin(x)*sin(y/2.0)+cos(x/2.5)*cos(y/1.5))
Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

Ок.

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост

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

Рисуем в 3d на c++ поверхность, заданную формулой C++, Программирование, 3D, Визуализация, Рендер, Геометрия, Алгебра, Вектор, Длиннопост
Показать полностью 15
430

Поляризация света или "волшебная плёнка"

Сегодня, хотелось бы рассказать вам о явлении поляризации света. Явление интересное и достаточно простое для понимания. Кроме этого, оно нашло широкое практическое применение. Это явление уже рассматривалось на Пикабу в постах о том как сделать "шпионский монитор" (ссылки давать не буду - множество их). Тем не менее, явление так и осталось без объяснения. Начнём с небольшого видео опыта, для того, чтобы вы поняли - что это такое:

А теперь объяснение. Если рассматривать свет, как электромагнитную волну, то его можно разложить на две составляющие – электрическую и магнитную. Электрическая и магнитная волны распространяются в одном направлении, но направление их колебания происходят под углом 90 градусов друг к другу (прошу прощения за "шакалов").

Поляризация света или "волшебная плёнка" Наука, Наука детям, Физика, Поляризация, Поляризационная плёнка, 3D, Длиннопост, Текст, Видео

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

Поляризация света или "волшебная плёнка" Наука, Наука детям, Физика, Поляризация, Поляризационная плёнка, 3D, Длиннопост, Текст, Видео

Именно такой свет поступает от большинства источников (солнце, лампочки и т.д.). Такие пучки свет называется неполяризованными. Так в чём же состоит явление поляризации?

Поляризация света – явление, при котором из светового пучка «убираются» все лишние электромагнитные волны. Остаются лишь те, которые лежат в определённой плоскости – плоскости поляризации (примечание для тех, кто ничего не понял: треугольный кубик можно засунуть в треугольное отверстие только повернув его на правильный угол. Пленка выполняет функцию такого сита. Она пропускает только правильно повернутые волны и не пропускает повернутые неправильно). Обычно для поляризации света используют специальную поляризационную плёнку.

Поляризация света или "волшебная плёнка" Наука, Наука детям, Физика, Поляризация, Поляризационная плёнка, 3D, Длиннопост, Текст, Видео

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

Но мы идём дальше. А что будет, если взять вторую такую же плёнку?

Поляризация света или "волшебная плёнка" Наука, Наука детям, Физика, Поляризация, Поляризационная плёнка, 3D, Длиннопост, Текст, Видео

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

А теперь, об использовании этого явления. Самое популярное это - 3D-поляризационные очки. 

Поляризация света или "волшебная плёнка" Наука, Наука детям, Физика, Поляризация, Поляризационная плёнка, 3D, Длиннопост, Текст, Видео

Принцип их работы прост до невероятности: На линзы очков наклеена поляризационная плёнка - на одной линзе - горизонтально, на другой - вертикально (в итоге угол между плоскостями поляризации - 90 градусов). В итоге: горизонтально поляризованное изображение видит только один глаз, а вертикально поляризованное - другой. Осталось лишь раздобыть специальный монитор, который будет транслировать "сдвоенное изображение" из картинок с горизонтальной и вертикальной поляризацией, каждое из которых будет попадать в нужный глаз (:

Кстати, эта технология используется в IMAX и очки на картинке выше тоже именно оттуда.

Спасибо за терпение, пытался объяснить всё как можно доступнее.

Показать полностью 4
Похожие посты закончились. Возможно, вас заинтересуют другие посты по тегам: