[英]How to get the angle (pitch/yaw) between two 3D vectors for an autoaim
我正在嘗試獲取兩個向量(我的相機位置和敵人位置)之間的角度來創建自動瞄准/瞄准機器人。
該游戲基於 Unity,它使用左手坐標系。 XYZ 是對的,向上,向前。
游戲也使用度數。
這是我正在嘗試的偽代碼,但它沒有給我正確的俯仰/偏航。
diff = camera_position - enemy_position
hypotenuse = sqrt(diff.x*diff.x + diff.y*diff.y)
angle.x = asinf(diff.z / hypotenuse) * (180 / PI);
angle.y = atan2(diff.y / diff.x) * (180 / PI);
angle.z = 0.0f;
有人可以幫我弄這個嗎? 我數學很差。
我正在嘗試獲取兩個向量之間的角度(我的相機位置和敵人位置)
在統一中:
使用Vector3
結構中的Angle
函數。
float angle = Vector3.Angle(camera_position, enemy_position);
或個人角度:
float angleX = Vector3.Angle(new Vector3(camera_position.x, 0, 0), new Vector3(enemy_position.x, 0, 0));
float angleY = Vector3.Angle(new Vector3(0, camera_position.y, 0), new Vector3(0, enemy_position.y, 0));
float angleZ = Vector3.Angle(new Vector3(0, 0, camera_position.z), new Vector3(0, 0, enemy_position.z));
編輯:
我沒有使用 Unity 引擎。 這是我創建的一個單獨的模塊,用於裝配我自己的自動瞄准。 我正在努力獲得正確的數學本身。
在 C++ 中:
代碼在下面的Angle
函數中解釋,這是最后一個函數
#include <iostream>
#include <numeric> //for inner_product
#include <vector> //For vector
#include <math.h> //For sqrt, acos and M_PI
float Dot(std::vector<float> lhs, std::vector<float> rhs);
float magnitude(std::vector<float> vec3);
float Angle(std::vector<float> from, std::vector<float> to);
std::vector<float> normalise();
int main()
{
std::vector<float> from{3, 1, -2};
std::vector<float> to{5, -3, -7 };
float angle = Angle(from,to);
std::cout<<"Angle: "<<angle<<std::endl;
return 0;
}
//Find Dot/ Scalar product
float Dot(std::vector<float> lhs, std::vector<float> rhs){
return std::inner_product(lhs.begin(), lhs.end(), rhs.begin(), 0);
}
//Find the magnitude of the Vector
float magnitude(std::vector<float> vec3)//<! Vector magnitude
{
return sqrt((vec3[0] * vec3[0]) + (vec3[1] * vec3[1]) + (vec3[2] * vec3[2]));
}
//Normalize Vector. Not needed here
std::vector<float> normalise(std::vector<float> vect)
{
std::vector<float> temp{0, 0, 0};
float length = magnitude(vect);
temp[0] = vect[0]/length;
temp[1] = vect[1]/length;
temp[2] = vect[2]/length;
return temp;
}
float Angle(std::vector<float> from, std::vector<float> to){
//Find the scalar/dot product of the provided 2 Vectors
float dotProduct = Dot(from, to);
//Find the product of both magnitudes of the vectors then divide dot from it
dotProduct = dotProduct / (magnitude(from) * magnitude(to));
//Get the arc cosin of the angle, you now have your angle in radians
float arcAcos = acos(dotProduct);
//Convert to degrees by Multiplying the arc cosin by 180/M_PI
float angle = arcAcos * 180 / M_PI;
return angle;
}
要計算兩個 3d 坐標之間的角度(以度為單位),您可以使用此 CalcAngle 函數:
#include <algorithm>
#define PI 3.1415927f
struct vec3
{
float x, y, z;
}
vec3 Subtract(vec3 src, vec3 dst)
{
vec3 diff;
diff.x = src.x - dst.x;
diff.y = src.y - dst.y;
diff.z = src.z - dst.z;
return diff;
}
float Magnitude(vec3 vec)
{
return sqrtf(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z);
}
float Distance(vec3 src, vec3 dst)
{
vec3 diff = Subtract(src, dst);
return Magnitude(diff);
}
vec3 CalcAngle(vec3 src, vec3 dst)
{
vec3 angle;
angle.x = -atan2f(dst.x - src.x, dst.y - src.y) / PI * 180.0f + 180.0f;
angle.y = asinf((dst.z - src.z) / Distance(src, dst)) * 180.0f / PI;
angle.z = 0.0f;
return angle;
}
並發症:
並非所有游戲都使用相同的角度和位置技術。 x、y 和 z 角度的最小值和最大值在每個游戲中都可能不同。 所有游戲的基本思想都是一樣的,它們只需要稍作修改即可匹配每個游戲。 例如,在編寫代碼的游戲中,X 值必須在最后變為負數才能工作。
另一個復雜因素是 X、Y 和 Z 並不總是在坐標和角度 vec3s 中表示相同的變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.