计算角度是否在两个角度之间

use*_*573 21 math trigonometry

所以我正在制作一个小游戏,我正在检查角色是否可以"看到"另一个角色A可以看到角色B,如果A在B的某个距离内,并且A的角度方向是+/- 45度角度B面对.

目前,我正在做一些计算,我正在检查是否

(facingAngle - 45) =< angleOfTarget =< (facingAngle + 45)
Run Code Online (Sandbox Code Playgroud)

除了当我们穿过360度线时,这种方法很好.

让我们说吧facingAngle = 359, angleOfTarget = 5.在这种情况下,目标只偏离中心6度,所以我希望我的函数返回true.不幸的是,5不在314和404之间.

ron*_*chn 23

试一试

anglediff = (facingAngle - angleOfTarget + 180 + 360) % 360 - 180

if (anglediff <= 45 && anglediff>=-45) ....
Run Code Online (Sandbox Code Playgroud)

原因是角度的差异facingAngle - angleOfTarget虽然是由于包裹效应,但可能会偏离360度.

然后加上180 + 360然后以模数360减去180,实际上只是将所有内容转换为-180到180度的范围(通过加或减360度).

然后,您可以轻松检查角度差异,是否在-45到45度之间.

  • 例如,在 facesAngle 为 0 且angleOfTarget 为 359 的情况下,这将失败。除非我遗漏了什么,否则你会得到 (0 - 359 + 180) % 360 - 180 = -359。faceAngle - angleOfTarget 减法周围需要一个绝对值。 (3认同)

Aln*_*tak 9

有一个三角解决方案可以避免包装问题.

我假设你有两个字符P1和(x,y)坐标P2.你已经指定你知道两者之间的距离,你可能用毕达哥拉斯定理计算了它们之间的距离.

您可以使用两个向量的点积来计算它们之间的角度:

A . B = |A| . |B| . cos(theta).
Run Code Online (Sandbox Code Playgroud)

如果你将它A作为facingAngle矢量[cos(fA), sin(fA)],它将具有|A|1的幅度.

如果你把B两个角色之间的向量作为向量,那么你得到的距离是:

cos(theta) = (cos(fA) * (P2x - P1x) + sin(fA) * (P2y - P1y)) / |B|
Run Code Online (Sandbox Code Playgroud)

|B|您已计算的距离在哪里.

您不需要实际取反余弦来查找theta,因为对于-45到+45的范围,您只需要检查cos(theta) >= 0.70710678(即1 / sqrt(2)).

这可能看起来有点复杂,但是你可能已经在你的程序中找到了所有必需的变量.


Sta*_*kov 8

这是我在网上找到的一个简单的功能,并进行了修改.它适用于任何角度(可以在0-360之外).(此功能适用于c,适用于Xcode.)

记住,它检查从角度A到角度B的COUNTER-CLOCKWISE.如果角度在:)之间,则返回YES(true)

首先,简单的转换功能使所有角度为1-360

//function to convert angle to 1-360 degrees
 static inline double angle_1to360(double angle){
 angle=((int)angle % 360) + (angle-trunc(angle)); //converts angle to range -360 + 360
 if(angle>0.0)
 return angle;
 else
 return angle + 360.0;
 }
Run Code Online (Sandbox Code Playgroud)

检查角度是否介于:)

//check if angle is between angles
 static inline BOOL angle_is_between_angles(float N,float a,float b) {
 N = angle_1to360(N); //normalize angles to be 1-360 degrees
 a = angle_1to360(a);
 b = angle_1to360(b);

 if (a < b)
 return a <= N && N <= b;
 return a <= N || N <= b;
 }
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

例如.检查角度300是否在180到10度之间:

BOOL isBetween=angle_is_between_angles( 300, 180,10);
Run Code Online (Sandbox Code Playgroud)

//返回是

  • 如果 trunc() 替换为 Math.floor(),则似乎适用于 Java。 (2认同)