我有一个物体,它面向一个特定的方向(例如)45度视野和极限视野范围。我已完成所有初始检查(四叉树节点和距离),但现在我需要检查特定对象是否在该视锥内(在这种情况下,如果我们可以看到它,则决定只跟随该对象)。

除了从 Direction - (FieldOfView / 2) Direction +(FieldOfView / 2)的每个度数投射光线(我现在正在这样做这太可怕了,进行这种能见度检查的最佳方法是什么?

有帮助吗?

解决方案

计算视图方向(理解为矢量)与从您开始并在对象处结束的矢量之间的角度。如果它属于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;

没有触发功能,只有一些乘法,除法和加法。大多数游戏引擎都有一个优化的矢量normalize()函数。

这是因为这个等式:

A · B = |A| * |B| * cos(Θ)

如果对矢量进行归一化(A - > An),则简化等式:

An · Bn = cos(Θ)

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

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

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

如果你正在做3D并且可以将观看范围定义为截头,那么你可以使用类似的东西 Frustrum Culling 技术。

已经有了很好的答案,但我只想给你一个Wolfire博客的链接,他们最近开始了一个采用“视野”的代数系列。方程作为一个例子。 去读它,它的写得好而且容易。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top