Cross Product and Angle Incorrect?

I’m slowly going crazy because of this weird problem I’m having. I’m trying to program my AI and the expected results are not coming up. So, I ran a quick test that should always return 90 degrees. I get the cross product of my characters forward rotation and get the yaw angle between the forward and the cross product. This should always return 90 degrees on a level plane but I’m not getting that.

//Get the left vector for the actor
FVector Lateral = FVector::CrossProduct(Bot->GetActorRotation().Vector().GetSafeNormal(), FVector(0, 0, 1));

//Offset the point by the actors location since it's a unit vector we don't want it at the origin 
FVector TurnExtent = Lateral + Bot->GetActorLocation();

//calculate the angle and output it to the log.
float angle = (Bot->GetActorLocation() - TurnExtent).Rotation().Yaw;
UE_LOG(LogTemp, Log, TEXT("angle: %f"), angle);

Results

LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 110.746773
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 113.297768
LogTemp: angle: 110.716896

This seems very strange to me so I tried some straight trig:

float angle = ((atan2(TurnExtent.X - Bot->GetActorLocation().X, TurnExtent.Y - Bot->GetActorLocation().Y)) * 180 / PI);

But it got me similar (but different results)

LogTemp: angle: 169.221909
LogTemp: angle: 168.195251
LogTemp: angle: 167.994247
LogTemp: angle: 167.793625
LogTemp: angle: 167.651367
LogTemp: angle: 167.651367
LogTemp: angle: 167.536423
LogTemp: angle: 167.536041

Am I getting the characters rotation incorrectly?

I think your math is just off.

 //calculate the angle and output it to the log.
 float angle = (Bot->GetActorLocation() - TurnExtent).Rotation().Yaw;

That is calculating the angle between the Bot’s position (which is probably interpreted as a direction from the origin), and TurnExtent which is a position + direction (again, interpreted as a direction from the origin). I’d simplify all this to unit vectors.

// This line assumes there is no Pitch/Roll on the actor.
const FVector& leftVector = Bot->getActorRotation().Vector().SafeNormal();
const FVector up(0.0f, 0.0f, 1.0f);
const FVector& crossVector = FVector::CrossProduct(leftVector, up);

// We can simply use the dot product to grab the angle.
float angle = FMath::Acos(FVector::DotProduct(leftVector, crossVector));

Worked like a charm. I was making it out to be way more complicated than it had to be because I was feeding it incorrect values. Sometimes going back to basic trig throws me for a loop :stuck_out_tongue:

Thanks Again.