【问题标题】:How to get the angle (pitch/yaw) between two 3D vectors for an autoaim如何获得自动瞄准的两个 3D 矢量之间的角度(俯仰/偏航)
【发布时间】:2017-02-01 13:06:23
【问题描述】:

我正在尝试获取两个向量(我的相机位置和敌人位置)之间的角度来创建自动瞄准/瞄准机器人。

游戏是基于 Unity 的,它使用左手坐标系。 X Y Z 向右,向上,向前。

游戏也使用度数。

这是我正在尝试的伪代码,但它未能给我正确的俯仰/偏航。

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;

有人可以帮我解决这个问题吗?我数学很差。

【问题讨论】:

标签: c++ math unity3d trigonometry algebra


【解决方案1】:

我正在尝试获取两个向量之间的角度(我的相机位置 和敌方位置)

在 Unity 中

使用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; 
}

【讨论】:

  • 我没有使用 Unity 引擎。这是我创建的一个单独的模块,用于装配我自己的自动瞄准。我正在尝试做正确的数学本身。
  • 上面写着“游戏是基于 Unity 的”,并且在其中标记了 unity。您应该在您的问题中进行编辑并将其包含在其中。
  • @Serlite 可能是真的,但文档说“返回从和到之间的角度”,这几乎与问题标题和正文相同.....
  • 我想我可以用它来看看 Angle 做了什么并手动移植它。这对我很有用。谢谢。
  • @user6871291 在 Stack Exchange 网络上有一些很好的资源来处理这类事情 - 您需要做的就是计算幅度和点积:math.stackexchange.com/questions/654315/…
【解决方案2】:

要计算两个 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 中并不总是代表相同的变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-28
    • 2012-08-02
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多