![]() |
|
||||||||||
|
|
|
|||||
|
Регистрация: Mar 2010
Сообщений: 137
|
Пишу трассировщик лучей.
Есть ядро, есть хороший математический аппарат, но возникла совершенно неожиданная и ужасно раздражающая проблема. Нужно посчитать угол отражённого луча... Думал - фигня, за пять минут решу. Ан нет! Забыл, что углы бывают отрицательные. Начал рассматривать все случаи и понял, что дело принимает нехороший оборот. Чтобы всё отражалось без глюков надо учитывать восемь случаев: зеркало имеет положительный угол, отрицательный, и четыре варианта для луча (выше зеркала, ниже его и для каждого угол положительный, или отрицательный)! Хуже всего, что надо смотреть расположение точки относительно отрезка. А это – векторное произведение! Два умножения и разница. Короче, плохо. Что делать, подскажете, а? Примечания: 1. Зеркало задано отрезком (на картинке зелёное). Его угол измеряется от -90 градусов до 90. Причина этого - сортированость вершин по X. 2. Угол луч измеряется от -180 градусов до 180. Обычный atan2. |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
__________________
Reality.getBounds(this); |
|
|||||
|
Регистрация: Mar 2010
Сообщений: 137
|
Я это читал. Собственно, сам вешал эту ссылку в ответ на чей-то пост тут.
Мой алгоритм лучше работает с углами. И, кстати, если бы был на хабре, поспорил бы с человеком, написавшим пост. Дело в том, что его способом требуется считать три векторных произведения. Это шесть умножений. И плюс суммы и разницы - опять-таки, векторов. Долго. Один косинус считать будет быстрее! Синус полчим по основному тождеству. Итого: косинус, умножение и разница. Я проверил. Такое должно считаться быстрее. Добавлено через 55 минут Вот только с углом проблема... |
|
|||||
|
Регистрация: Apr 2010
Адрес: Earth
Сообщений: 1,897
|
Не нужно преувеличивать:
public class Vector2 { ............ public function mirror( mirrorVec:Vector2 ):void { var v:Vector2 = new Vector2( mirrorVec.y, -mirrorVec.x ); v.normalize(); var m:Number = -2.0 * (this.x * v.x + this.y * v.y); this.x += m * v.x; this.y += m * v.y; } ............ } Если mirrorVec будет единичным, а он должен быть единичным исходя из задачи, то все сведется к паре действий: public function mirror( mirrorVec:Vector2 ):void { var m:Number = -2.0 * (this.x * mirrorVec.y - this.y * mirrorVec.x); this.x += m * mirrorVec.y; this.y -= m * mirrorVec.x; } ![]()
__________________
Загружаем картинки, минуя ошибки безопасности Последний раз редактировалось i.o.; 01.02.2011 в 00:11. |
|
|||||
|
Регистрация: Mar 2010
Сообщений: 137
|
i.o., спасибо за код. Но...
Цитата:
Но проблема в том, что зеркало не нормализировано. Добавлено через 1 час 16 минут И, кстати, что такое -2.0 ? Добавлено через 1 час 38 минут Глянул на сайте (ссылка чего-то побилась, а источник уже не помню). Понял, откуда формула. Да, верно. Способ мне нравится. Он универсальный. В 2Д-случае всё-таки косинус рулит, но для 3Д - только вектора. Иначе запарюсь всё считать. Буду думать. Добавлено через 70 часов 46 минут Что ж... Написал я алгоритм. Во-первых, вот этот код: var m:Number = -2.0 * (this.x * mirrorVec.y - this.y * mirrorVec.x); this.x += m * mirrorVec.y; this.y -= m * mirrorVec.x; Правильность проверю. Во-вторых, подумал я, и решли, что с углом работать всё-таки логичнее. По нескольким причинам: 1. Для оптики естественнее работа с углами. Они там везде фигурируют. 2. Расчёт одного косинуса и синуса будет быстрее, чем действия, необходимые для векторного решения. И, если подумать, его можно перенести на 3D. 3. Задавать луч точкой и углом логичнее, чем двумя точками. Заодно орт считать удобнее. Короче, буду опять мучить себя поисками углового решения... Код того, что есть пока (не работает, но можно составить общее впечатление по кол-ву действий): var mul:Number = updateRay.Norm.X*updateRay.Norm.Y+updateRay.DeltaX*updateRay.DeltaY; var newX:Number = updateRay.End.X+updateRay.DeltaX-updateRay.Norm.X*2*mul; var newY:Number = updateRay.End.Y+updateRay.DeltaY-updateRay.Norm.Y*2*mul; res.push(new Ray2d(updateRay.End, Math.atan2(newY,newX))); Последний раз редактировалось semenyakinVS; 04.02.2011 в 01:05. Причина: Убрал немотивированный наезд |
![]() |
![]() |
Часовой пояс GMT +4, время: 22:34. |
|
|
« Предыдущая тема | Следующая тема » |
| Теги |
| ray tracing , оптика , углы |
|
|