Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Вектры в пространстве


Автор: KonovalovSerega 19.1.2007, 20:32
Привет!!!
Я тут разбирался с DirectX и у меня возникла одна проблема.  smile 
Суть проблемы такова:
               У меня есть луч опред.  вектором начала и направления и 
есть много прямоугольников. Мне нужно определить в какой прямоугольник попал луч(если вообше попал).
Кто знает как решить эту проблему, напишите как(желательно по понятней).

Зарание спосибо!  smile 




Автор: maxim1000 19.1.2007, 22:40
ну, например, так:
луч пересекает прямоугольник тогда и только тогда, когда он пересекает хотя бы одну сторону, так что достаточно проверить пересечение с лучом для каждого отрезка
для отрезка можно поступить так:
- считаем модуль угла между лучом и направлением из его начала на одну вершину
- считаем модуль угла между лучом и направлением на вторую вершину
- считаем модуль угла между направлениями на вершины
если сумма первых равна третьему, значит, пересекает

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

Автор: Bitter 20.1.2007, 02:03
maxim1000, это ж для 2D случая... насколько я понял, нужно для 3D (в пространстве)

Автор: Artemios 20.1.2007, 02:21
Решается система уравнений: 2 линейных уравнения от 3-х переменных, задающие плоскость, в которой лежит квадрат, 3-е линейное уравнение задает прямую для луча. Решение системы уравнений является точкой пересечения прямой и плоскости, и останется выяснить, принадлежит ли точка в плоскости квадрату в той же плоскости. Эту проверку можно сделать несколькими способами, например: нормали из точки, построенные к противолежащим сторонам квадрата, должны быть противоположно направлены.

Добавлено @ 02:30 
Цитата(Artemios @  20.1.2007,  02:21 Найти цитируемый пост)
например: нормали из точки, построенные к противолежащим сторонам квадрата, должны быть противоположно направлены. 

Точнее, не к сторонам квадрата, а к прямым, на которых эти стороны лежат.
Другой вариант: если точка внутри квадрата, то все нормали от нее к прямым, на которых лежат стороны квадрата, пересекают эти прямые именно внутри отрезков-сторон квадрата. Т.е. считаем точку пересечения 2-х прямых (прямяя для стороны квадрата и нормаль к ней из исследуемой точки). Получили точку пересечения -- считаем, принадлежит ли она отрезку (конкретной стороне квадрата). И так для всех 4-х сторон.

Автор: maxim1000 20.1.2007, 02:47
Цитата(Bitter @  20.1.2007,  01:03 Найти цитируемый пост)
это ж для 2D случая...

и то правда, просто прочитал "прямоугольники" в голове сразу "2D"

Добавлено @ 02:52 
О... кстати... придумал ещё один способ:
проектируем квадрат на плоскость, перпендикулярную лучу, и проверяем, лежит ли в нём точка (0,0) (после проекции уже 2D получается)
правда, это - скорее, способ для прямой и квадрата, нужно ещё проверить направление на точку пересечения

зато, по идее, должно работать, когда всё (и луч, и прямоугольник) лежит в одной плоскости, т.е. единственной точки пересечения нет

Автор: $tatic 20.1.2007, 11:41
В DirectX есть готовая функция для этого. К сожалению, сейчас не помню как называется smile

Автор: Bitter 20.1.2007, 15:18
По поводу сообщения Artemios'a: очень сложный алгоритм, в плане времени вычисления. Однако проверить пересикается ли луч с плоскостью можно так:

Point = A + c*(n*(B-A)/(n*c))

где 
      n - нормаль к плоскости
      B - любая вершина прямоугольника (а вообще точка, лежащая на плоскости)
      A - начало луча
      с - направление луча

      n*c - скалярное произведение векторов (угол между векторами). Если n*c=0 луч и плоскость паралельны
      n(B-A) - тоже скалярное произведение (так как B-A - вектор)

Решив это, получим точку пересечения луча с плоскостью. Теперь нужно выяснить лежит ли точка в прямоугольнике или треугольнике.

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

Автор: Artemios 21.1.2007, 00:47
Цитата(Bitter @  20.1.2007,  15:18 Найти цитируемый пост)
По поводу сообщения Artemios'a: очень сложный алгоритм, в плане времени вычисления. Однако проверить пересикается ли луч с плоскостью можно так:

Point = A + c*(n*(B-A)/(n*c))

где 
      n - нормаль к плоскости
      B - любая вершина прямоугольника (а вообще точка, лежащая на плоскости)
      A - начало луча
      с - направление луча

      n*c - скалярное произведение векторов (угол между векторами). Если n*c=0 луч и плоскость паралельны
      n(B-A) - тоже скалярное произведение (так как B-A - вектор)

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

Автор: Bitter 21.1.2007, 01:15
Artemios, так я ж Вами предложенный метод и описал smile. Только систему записал одним уравнением smile

Автор: Artemios 21.1.2007, 03:09
smile
Цитата(Artemios @  21.1.2007,  00:47 Найти цитируемый пост)
и что-то мне подсказывает, что с математической точки зрения это "абсолютно те же яйца, но боком"


а зацепился я на противопоставлении:
Цитата(Bitter @  20.1.2007,  15:18 Найти цитируемый пост)
По поводу сообщения Artemios'a: очень сложный алгоритм, в плане времени вычисления. Однако проверить пересикается ли луч с плоскостью можно так:


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)