获取有符号的角度值

Getting a signed angle value

我在求两个向量之间的角度时遇到了问题。我在蓝图中有这段代码(下图),它使用点积来计算两个向量之间夹角的余弦值。

但是,这个方法似乎没有给我完整的信息——我仍然无法确定我正在跟踪的对象是在我的左边还是右边。我相信这是因为cos是 even 功能,不提供有关角度符号的信息。

有什么方法可以确定角度的有符号值吗?可能是一些 C++ 魔法?在这种情况下,我非常感谢您的帮助。

另一个答案对您的特定用例有很好的解决方案,因为您可以使用旋转器快速找到演员的局部正确方向。更一般地(例如如果不涉及旋转器),如果您需要从某个任意上轴的角度获取角度及其相对方向,您可以使用此函数:

// Header
UFUNCTION(BlueprintPure)
static void AngleAndDirection(const struct FVector& FromNormalized, 
        const struct FVector& ToNormalized, 
        const struct FVector& UpAxisNormalized, 
        float& OutAngle, float& OutDirection);

// Source
void UClassName::AngleAndDirection(const FVector& FromNormalized, 
        const FVector& ToNormalized, const FVector& UpAxisNormalized, 
        float& OutAngle, float& OutDirection)
{
    OutAngle = UKismetMathLibrary::Acos(
            FVector::DotProduct(FromNormalized, ToNormalized));
    FVector Right = FVector::CrossProduct(UpAxisNormalized, FromNormalized);
    float Dot = FVector::DotProduct(UpAxisNormalized, Right);
    OutDirection = UKismetMathLibrary::SignOfFloat(Dot);
}

其中:

  • FromNormalizedToNormalized,以及 UpAxisNormalized(当然)归一化了

  • OutDirection 如果 ToNormalized 在相对的右边,则为正,如果在左边,则为负,如果两者都不是(可以在前面,上面,下面,或直接在后面),则为零)

  • OutAngle 以弧度为单位。

如果需要学位,可以使用DegACos代替Acos

如果您正在使用此功能,可以将其放入 Blueprint Function Library 中,以便您可以将其与您的蓝图一起使用。

点积只会给出两个向量所成角度的余弦值。同向为正,相反为负,垂直为0

只需检查“RightDirection”即可得到与原始点积对应的符号。

通过这样做,您将排除由基本方向给出的零点,因此当零时替换相反的轴。

这是蓝图伪代码:

   Vector TargetDirection = Normalize(Player.GetActorLocation - Object.GetActorLocation);
   float LR = dot(TargetDirection, Player.GetActorRotation.GetRightVector);
   float SignLR = Sign(LR); // returns -1,0,1
   float Angle = dot(TargetDirection,Player.GetActorRotation.GetForwardVector);

// catch the dot product zeros at(0,90,180,270...) 
// if is a float comparison object with the bool output passed to a branch

   if(Angle == 0) Angle = LR; // pick a direction (90 degrees left or right)
   if(SignLR == 0) SignLR = Angle; //pick a direction


   float Signed Angle = SignLR * Angle;

注意:不需要变量,在实现此代码时,输​​出引脚直接连接到多个输入。