2008-10-15 82 views
9

我有一个物体,它面对着(例如)45度视场的特定方向,以及极限视野范围。我已经完成了所有初始检查(Quadtree节点和距离),但是现在我需要检查一个特定的对象是否在该视图锥体内(在这种情况下,如果我们可以看到它,则仅决定跟随该对象)。如何检查一个游戏对象是否可以看到另一个游戏对象?

除了从Direction - (FieldOfView/2)Direction + (FieldOfView/2)(我现在这样做,这是可怕的)每个学位投射射线,什么是做这种可见性检查的最佳方法是什么?

回答

9

计算你的视线方向(理解为矢量)和从你开始到结束的向量之间的角度。如果它落在FieldOfView/2下,则可以查看该对象。

这角度:

arccos(scalarProduct(viewDirection, (object - you))/(norm(viewDirection)*norm(object - you))). 
+0

谢谢,正是我在找的东西。我认为这可能是基于我已有的最简单的方法。 – AshtonKJ 2008-10-15 05:42:27

2

如果你正在做3D和可以定义可视范围为平截,那么你可以使用类似这样的Frustrum Culling技术的东西。

3

获取观看者的方向矢量和从观看者到目标的矢量之间的角度。如果该角度小于(FieldOfView/2),则目标位于观察者的视野内。

如果你的载体是2D或3D,这将工作相同的方式。 (在3D中,如果你有一个视锥体而不是锥体,那么你需要将角度分成两个分量。)你只需要找到两个向量之间的角度。

如果要测试比单个点大的目标,则每个目标都需要多个点,例如边界框的拐角。如果从观察者到这些点中的任何一个的矢量在视野内给出一个角度,则该框的该角是可见的。

10

我曾经在视频游戏行业工作过,我可以说每个框架都做arccos这样的trig函数并不理想。相反,你预先计算角度的余弦的锥:

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(Θ) 

如果规范化向量(A - >的),公式被简化:

An · Bn = cos(Θ) 
+0

谢谢你。我喜欢限制每帧三角函数的数量。我肯定会考虑尝试这一个(可惜,只有一次考试完成)。 – AshtonKJ 2008-11-03 05:21:48

1

好的答案已,但我只是想给你一个链接到Wolfire博客的链接,他们最近开始了一个以“视场”方程为例的代数系列。 Go read it,它写得很好,很容易。