Взгляните на следующие примеры на AdventureWorks.
with member [Measures].[CountTest]
as
count(existing [Product].[Subcategory].members - [Product].[Subcategory].[All])
select
{
[Measures].[Internet Sales Amount],[Measures].[CountTest]
}
on columns,
{
([Product].[Category].[Category]
,[Product].[Subcategory].[Subcategory] -- comment this line for the second result
)
}
on rows
from [Adventure Works]
Теперь прокомментируйте указанную строку для родительского представления.
Вычислите угол между своим направлением представления (понятый как вектор) и вектором, который запускается в Вас и заканчивается в объекте. Если это подпадает под FieldOfView/2, можно просмотреть объект.
Тот угол:
arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).
Я работал в промышленности видеоигры, и я могу сказать, что, делая аккуратные функции как arccos каждый кадр является меньше, чем идеал. Вместо этого Вы предварительно вычисляете косинус угла для конуса:
float cos_angle = cos(PI/4); // 45 degrees, for example
Затем каждый кадр, который можно быстро проверить, падает ли точка в том конусе путем сравнения этого со скалярным произведением конуса и.
vector test_point_vector = normalize(test_point_loc - cone_origin);
float dot_product = dot(normalized_cone_vector, text_point_vector);
bool inside_code = dot_product > cos_angle;
Нет никаких аккуратных функций, просто некоторое умножение, разделение и дополнение. Большинство игровых механизмов имеет оптимизированный, нормализуют () функцию для векторов.
Это работает из-за этого уравнения:
A · B = |A| * |B| * cos(Θ)
При нормализации векторов (->), уравнение упрощено:
An · Bn = cos(Θ)
Заставьте угол между вектором заголовка средства просмотра и вектором от средства просмотра предназначаться. Если тот угол является меньше, чем (FieldOfView/2), то цель находится в поле зрения средства просмотра.
Если Ваши векторы будут 2-ми или 3-ми, то это будет работать тот же путь. (В 3D, если у Вас есть представление frustum вместо конуса, затем необходимо будет разделить углы на два компонента.) Просто необходимо найти угол между этими двумя векторами.
Если Вы захотите протестировать цели, которые больше, чем единственная точка, то Вам будут нужны несколько точек для каждой цели, таких как углы ограничительной рамки. Если вектор от средства просмотра до какой-либо из этих точек дает угол в поле зрения, то тот угол поля видим.
Если Вы делаете 3D и можете определить диапазон просмотра как frustrum, то можно использовать что-то подобное этому Frustrum Отбор техники.
Уже хорошие ответы, но я просто хотел дать вам ссылку на блог Wolfire, они недавно начали серию по алгебре, в которой в качестве примера используется уравнение «поля зрения». Прочтите , он хорошо написан и прост.