2016-12-21 6 views
0

Как показано ниже, предположим, что имеется виртуальная камера, указывающая на объект, и оба они определяются ориентацией и положением относительно глобальной системы координат. На рисунках черный обозначает GCS, а синий обозначает LCS.Как рассчитать угол обзора объекта в 3D

Problem

Некоторые объекты, такие как экраны или светодиоды в этом случае, имеют угол обзора. Их можно увидеть только, например, если угол к наблюдателю находится в пределах ± 70 °

Чтобы решить эту проблему, я предпринял шаги, продемонстрированные следующим псевдокодом. Там, где это применимо, мы работаем в правой системе координат, используя внешние вращения, применяемые в порядке ZYX.

LEDToWorldTransform = LED.Transform; 
CameraToWorldTransform = Camera.Transform; 
WorldToCameraTransform = CameraToWorldTransform.Inverse; 
CameraToLEDTransform = WorldToCameraTransform * LEDToWorldTransform; 

Как я понимаю, CameraToLEDTransform теперь должен содержать перевод и вращение светодиода относительно камеры системы координат. Для целей визуализации:

Partial Solution

Сейчас это где я застрял, глядя на компоненты эйлеров CameraToLEDTransform Я думаю, мы можем заключить, что Z компонент вращения относительно системы координат камеры не влияет просмотр светодиода. Я попробовал следующее, что я не уверен, что это правильно. Обратите внимание, что на третьем этапе я пытаюсь изменить направление одной из осей Z таким образом, что они указывают в одном направлении

R_Z, R_Y, R_X = CameraToLEDTransform.Rotation.Eulers 
CameraToLEDTransform.Rotation.Eulers = 0, R_Y, R_X 
CameraToLEDTransform.Rotation *= Rotation.AngleAxis[180deg,X] 
Angle, Axis = CameraToLEDTransform.Rotation.AngleAxis 

Это дает ответ, который вроде выглядит правильно, но я подозреваю, что что-то может быть, не так, как после моей логике я должен также быть в состоянии заменить третий шаг с:

CameraToLEDTransform.Rotation *= Rotation.AngleAxis[180deg,Y] 

Однако, это не так, и я получаю другую (и, конечно, неправильно) ответ. Этот подход может быть совершенно неправильным, и я, конечно, не понимаю, почему вращение 180 вокруг X отличается от вращения 180 вокруг Y в этой ситуации. Возможно, альтернативным подходом было бы использование продукта Dot для вычисления угла, однако я думаю, что это работает только между двумя векторами, а не двумя вращениями. Кажется, что проектирование двух новых векторов, основанных на ориентации двух объектов, будет очень близким к приближению ...

ответ

2

Использование точечного продукта не является круглым приближением, это правильный подход . Вам понадобится использовать точечный продукт между вектором направления обзора камеры и нормальным (то есть вектором от наблюдателя до светодиода/объекта), чтобы получить косинус требуемого угла. Если объект является поверхностью, как экран, вы можете использовать вместо этого нормаль поверхности.

// normalized returns a unit vector 
Vector3 normal = (led.position - observer.position).Normalized(); 
Vector3 lookDirection = observer.lookDirection; // Should be a unit vector 

float cosAngle = Vector3.Dot(normal, lookDirection); 

При проверке, если угол находится в пределах требуемого диапазона, мы можем использовать следующее свойство функции cos избежать acos вызова:

Если -angle <= theta <= angle, cos(theta) >= cos(angle). (Попробуйте!)

Ваш чек будет выглядеть следующим образом:

// You can constantize or precompute this 
float cosViewingAngle = cos(deg2rad(70)); 
bool inViewingAngle = cosAngle >= cosViewingAngle; 
+0

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

Смежные вопросы