获取有符号的角度值
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);
}
其中:
FromNormalized
和 ToNormalized
,以及 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;
注意:不需要变量,在实现此代码时,输出引脚直接连接到多个输入。
我在求两个向量之间的角度时遇到了问题。我在蓝图中有这段代码(下图),它使用点积来计算两个向量之间夹角的余弦值。
但是,这个方法似乎没有给我完整的信息——我仍然无法确定我正在跟踪的对象是在我的左边还是右边。我相信这是因为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);
}
其中:
FromNormalized
和ToNormalized
,以及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;
注意:不需要变量,在实现此代码时,输出引脚直接连接到多个输入。