Форум программистов, компьютерный форум, киберфорум
Наши страницы
OpenGL
Войти
Регистрация
Восстановить пароль
 
General_TaO
3 / 3 / 1
Регистрация: 01.07.2017
Сообщений: 133
#1

Нахождение координат пересечения луча с вертикальной плоскостью - OpenGL

03.01.2018, 21:18. Просмотров 247. Ответов 7
Метки нет (Все метки)

Здравствуйте, уважаемые форумчане!

Работаю над выбором объекта в сцене с помощью центра экрана. Использую FPS-камеру. Камера имеет координата и углы наклона в градусах относительно осей мировых координат. У меня есть квадрат, расположенной вертикально и параллельно оси Z и имеет расстояние n до камеры. Используя углы и n, я нахожу x и y координаты точки пересечения луча "взгляда" камеры с плоскостью (см. чертеж на картинке ниже).

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

В примере у меня есть белый квадрат, которая имела координаты вычисленной точки пересечения. Есть также зеленоватый квадрат, который расположен в центре СК, в той же плоскости, что и белый квадрат.

В коде эти вычисления выглядят так:


C++ (Qt)
1
2
3
4
5
6
7
8
9
float n =camera.Position.x;
    float w = pow(sin(glm::radians(camera.Angles.y))/cos(glm::radians(camera.Angles.y)),2)*pow(sin(glm::radians(camera.Angles.x))/cos(glm::radians(camera.Angles.x)),2);
    float tg_a = sin(glm::radians(camera.Angles.x))/cos(glm::radians(camera.Angles.x));
    float y = sqrt(fabs((-pow(n,2)*w - pow(n*tg_a, 2))/(w-1)));
    float x = sqrt(fabs(pow(y/(sin(glm::radians(camera.Angles.x))/cos(glm::radians(camera.Angles.x))),2) - pow(n,2)));
        if (sin(glm::radians(camera.Angles.x)) < 0) y=-y;
        if (sin(glm::radians(camera.Angles.y)) < 0) x=-x;
       y = y+camera.Position.y;
       x = x+camera.Position.x;
Если есть какие-то замечания, советы или вопросы - пишите. Буду благодарен за любую предоставленную помощь.
http://www.cyberforum.ru/turbo-pascal/thread800305.html
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.01.2018, 21:18
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Нахождение координат пересечения луча с вертикальной плоскостью (OpenGL):

Кто знает секторную антену с вертикальной плоскостью больше чем 30 градусов
Кто знает секторную антену с вертикальной плоскостью больше чем 30...

Проверка пересечения луча с анимационной моделью
Если с не анимационными моделями проверять пересечение луча с треугольниками...

Найти элементы пересечения луча в матрице
Всем доброго дня! Помогите пожалуйста найти элементы матрицы которые...

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

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

7
General_TaO
3 / 3 / 1
Регистрация: 01.07.2017
Сообщений: 133
03.01.2018, 21:21  [ТС] #2
. . .
0
Миниатюры
Нахождение координат пересечения луча с вертикальной плоскостью   Нахождение координат пересечения луча с вертикальной плоскостью   Нахождение координат пересечения луча с вертикальной плоскостью  

Нахождение координат пересечения луча с вертикальной плоскостью   Нахождение координат пересечения луча с вертикальной плоскостью  
General_TaO
3 / 3 / 1
Регистрация: 01.07.2017
Сообщений: 133
04.01.2018, 13:13  [ТС] #3
На моём чертеже есть ошибка: диагональ задней плоскости куба не является с.
0
Igor3D
1227 / 594 / 74
Регистрация: 01.10.2012
Сообщений: 2,844
04.01.2018, 13:16 #4
Лучший ответ Сообщение было отмечено General_TaO как решение

Решение

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

- есть луч выходящий из точки rayPos и имеющий напр-е rayDir. Найти точку пересечения луча с плоскостью заданной нормалью N и точкой p.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// возвращает расстояние по лучу от rayPos до точки пересечения
// отрицательное расстояние значит пересечение не найдено (луч уходит)
// N должно быть нормировано
float RayPlaneIntersect( const vec3 & rayPos, const vec3 & rayDir, const vec3 & N, const vec3 & p )
{
 const float eps = 1.0e-5f;
 float ratio = dot(N, rayDir);   // косинус нормали с лучом
 if (fabs(ratio) < eps) return -1.0f;  // луч параллелен плоскости
 float d = dot(N, p - rayPos);  // расстояние от плоскости до rayPos по нормали
 return d / ratio;     // возвращаем расстояние по лучу
}    
 
// пример использования
vec3 inters;
float t = RayPlaneIntersect(rayPos, rayDir, N, p);
if (t >= 0.0f) {
 inters = rayPos + rayDir * t; // находим точку пересечения
 ...
}
Правда от вычисления пересечения с плоскостью толку мало - дальше надо будет найти попадает ли точка пересечения в пр-к. Ну это еще впереди.

Судя по тому что Вы рассказали для данной задачи
p = (0, 0, 0);
N = (1, 0, 0);
rayPos = camera.Position;
rayDir = ???
Цитата Сообщение от General_TaO Посмотреть сообщение
Камера имеет координата и углы наклона в градусах относительно осей мировых координат.
А на рисунке у Вас углы с плоскостями мировой СК - это совсем не одно и то же. Что у Вас angles - не знаю, может просто углы поворота. Как найти вектор луча в мире - недавно разговор был

Не по теме:

C++
1
float w = pow(sin(glm::radians(camera.Angles.y))/cos(glm::radians(camera.Angles.y)),2)*pow(sin(glm::radians(camera.Angles.x))/cos(glm::radians(camera.Angles.x)),2);
Еще раз увижу подобный кал - больше Вам не отвечу. Опыта мало - не беда, но надо стараться, а не ляпать абы как

1
General_TaO
3 / 3 / 1
Регистрация: 01.07.2017
Сообщений: 133
04.01.2018, 21:54  [ТС] #5
Не совсем понимаю, как ratio может быть косинусом. Ведь косинус - это скалярное произведение векторов, делённое на произведение их длин.
И что такое p?

Вы уж простите за моё оформление, у меня пока лапки не эволюционировали в ручки...
0
Igor3D
1227 / 594 / 74
Регистрация: 01.10.2012
Сообщений: 2,844
05.01.2018, 10:43 #6
Цитата Сообщение от General_TaO Посмотреть сообщение
Не совсем понимаю, как ratio может быть косинусом. Ведь косинус - это скалярное произведение векторов, делённое на произведение их длин.
Верное замечание, это я так упростил для понятности. Строго говоря "проекция луча на направление нормали"
Цитата Сообщение от General_TaO Посмотреть сообщение
И что такое p?
Любая точка лежащая на плоскости (напр центр пр-ка или один из его вертексов)
Цитата Сообщение от General_TaO Посмотреть сообщение
у меня пока лапки не эволюционировали в ручки...
А сами собой они и не cэволюционируют, надо прилагать усилия. Ведь давно хватает умения написать хотя бы так
C++
1
2
3
4
5
inline float Sqr( float f ) { return f * f; }  // обычно template
...
float angleX = glm::radians(camera.Angles.x);
float angleY = glm::radians(camera.Angles.y);
float w = Sqr(tan(angleY)) / Sqr(tan(angleX));
А мы чего-то ждем и копипастим. Нехорошо.
0
General_TaO
3 / 3 / 1
Регистрация: 01.07.2017
Сообщений: 133
05.01.2018, 13:32  [ТС] #7
Так-с. Вы забыли уточнить, что rayDir - это EndPoint - StartPoint, где StartPoint и EndPoint - центр камеры и направление луча соответственно. Эх, сколько я времени на это потратил. Но не ошибается тот, кто ничего не делает, как говорится)). Спасибо за помощь.
0
Igor3D
1227 / 594 / 74
Регистрация: 01.10.2012
Сообщений: 2,844
06.01.2018, 11:24 #8
Цитата Сообщение от General_TaO Посмотреть сообщение
Вы забыли уточнить, что rayDir - это EndPoint - StartPoint, где StartPoint и EndPoint - центр камеры и направление луча соответственно.
EndPoint - это координата (а не направление/вектор), для расчетов эта координата не нужна
C++
1
2
rayDir = EndPoint - StartPoint;  // координата - координата = вектор
EndPoint = StartPoint + rayDir;  // координата + вектор = координата
Если позиция камеры изменится, то EndPoint тоже изменится, а rayDir нет

Луч можно задать 2 точками или точкой и вектором, традиционно используется второй способ
0
06.01.2018, 11:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.01.2018, 11:24
Привет! Вот еще темы с решениями:

Точка пересечения луча и поверхности сферы
Подскажите самый простой способ. Точка пересечения луча и поверхности сферы. ...

Найти точки пересечения луча и окружности
Given a sphere of radius sphereRadius, center point is sphereCenter and a ray...

Точка пересечения луча (прямой) с треугольником.
Как найти точку пересечения луча (прямой) с треугольником в пространстве? ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru